1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

+complete all features; +testing in progress;

This commit is contained in:
Nickolay 2011-10-12 08:36:05 +03:00
parent 6a5589ef51
commit 20757c2efd
8 changed files with 687 additions and 596 deletions

View File

@ -63,8 +63,8 @@ public:
QString getSayOrder() const { return _sayOrder; }
void setSayOrder(QString text) { _sayOrder = text; }
double singleValue() const { return _singleValue; }
void setSingleValue(double value) { _singleValue = value; }
QVariant singleValue() const { return _singleValue; }
void setSingleValue(QVariant value) { _singleValue = value; }
double valueRange2() const { return _valueRange2; }
void setValueRange2(double value) { _valueRange2 = value; }
@ -131,6 +131,7 @@ public:
QTimer* getTimer() const { return _timer; }
void startTimer(int value);
void restartTimer();
void stopTimer();
void disposeTimer();
@ -141,7 +142,7 @@ public:
void disposeExpireTimer();
bool isNowPlaying;
bool firstStart;
bool _isPlayed;
static QStringList sayOrderValues;
static QStringList retryValues;
@ -184,8 +185,8 @@ private:
//! order in what sounds 1-3 will be played
QString _sayOrder;
//! one-side range, value maybe lower or greater
double _singleValue;
//! one-side range, value(numeric or ENUM type) maybe lower, greater or in range
QVariant _singleValue;
//! both-side range, value should be inside the range
//double _valueRange1;

View File

@ -59,7 +59,7 @@ QStringList NotificationItem::retryValues;
NotificationItem::NotificationItem(QObject *parent)
: QObject(parent)
, isNowPlaying(0)
, firstStart(true)
, _isPlayed(false)
, _timer(NULL)
, _expireTimer(NULL)
, _soundCollectionPath("")
@ -77,10 +77,12 @@ NotificationItem::NotificationItem(QObject *parent)
, _expireTimeout(eDefaultTimeout)
, _mute(false)
{
NotificationItem::sayOrderValues.clear();
NotificationItem::sayOrderValues.append(cStrBefore1st);
NotificationItem::sayOrderValues.append(cStrBefore2nd);
NotificationItem::sayOrderValues.append(cStrAfter2nd);
NotificationItem::retryValues.clear();
NotificationItem::retryValues.append(cStrRetryOnce);
NotificationItem::retryValues.append(cStrRetryInstantly);
NotificationItem::retryValues.append(cStrRetry10sec);
@ -92,7 +94,7 @@ NotificationItem::NotificationItem(QObject *parent)
void NotificationItem::copyTo(NotificationItem* that) const
{
that->isNowPlaying = isNowPlaying;
that->firstStart = firstStart;
that->_isPlayed = _isPlayed;
that->_soundCollectionPath = _soundCollectionPath;
that->_currentLanguage = _currentLanguage;
that->_soundCollectionPath = _soundCollectionPath;
@ -142,7 +144,8 @@ void NotificationItem::restoreState(QSettings* settings)
setSound2(settings->value(QLatin1String("Sound2"), tr("")).toString());
setSound3(settings->value(QLatin1String("Sound3"), tr("")).toString());
setSayOrder(settings->value(QLatin1String("SayOrder"), tr("")).toString());
setSingleValue(settings->value(QLatin1String("Value1"), tr("")).toDouble());
QVariant value = settings->value(QLatin1String("Value1"), tr(""));
setSingleValue(value);
setValueRange2(settings->value(QLatin1String("Value2"), tr("")).toDouble());
setRetryString(settings->value(QLatin1String("Repeat"), tr("")).toString());
setLifetime(settings->value(QLatin1String("ExpireTimeout"), tr("")).toInt());
@ -185,16 +188,26 @@ void NotificationItem::deseriaize(QDataStream& stream)
stream >> this->_mute;
}
void NotificationItem::startTimer(int value)
void NotificationItem::startTimer(int msec)
{
if (!_timer) {
_timer = new QTimer(this);
_timer->setInterval(value);
_timer->setInterval(msec);
}
if (!_timer->isActive())
_timer->start();
}
void NotificationItem::restartTimer()
{
if (!_timer) {
if (!_timer->isActive())
_timer->start();
}
}
void NotificationItem::stopTimer()
{
if (_timer) {
@ -311,17 +324,26 @@ QStringList valueToSoundList(QString value)
return digitWavs;
}
QString stringFromValue(QVariant value, UAVObjectField* field)
{
Q_ASSERT(field);
Q_ASSERT(!value.isNull());
QString str;
if (UAVObjectField::ENUM == field->getType()) {
if(!field->getOptions().contains(value.toString()))
return QString();
str = value.toString();
} else {
str = QString("%L1").arg(value.toDouble());
}
return str;
}
QString NotificationItem::toString()
{
QString str;
QString value;
UAVObjectField* field = getUAVObjectField();
if (UAVObjectField::ENUM == field->getType()) {
Q_ASSERT(singleValue() < field->getOptions().size());
value = field->getOptions().at(singleValue());
} else {
value = QString("%L1").arg(singleValue());
}
QString value = stringFromValue(singleValue(), field);
int pos = getValuePosition(getSayOrder().trimmed());
QStringList lst;
@ -353,15 +375,8 @@ QStringList& NotificationItem::toSoundList()
// tips:
// check of *.wav files exist needed for playing phonon queues;
// if phonon player don't find next file in queue, it buzz
QString value;
UAVObjectField* field = getUAVObjectField();
if (UAVObjectField::ENUM == field->getType()) {
Q_ASSERT(singleValue() < field->getOptions().size());
value = field->getOptions().at(singleValue());
} else {
value = QString("%L1").arg(singleValue());
}
QString value = stringFromValue(singleValue(), field);
// generate queue of sound files to play
_messageSequence.clear();

View File

@ -31,7 +31,7 @@
#ifdef DEBUG_NOTIFIES_ENABLE
QDebug qNotifyDebug()
{
return qDebug();
return qDebug() << "[NOTIFY_PLG]";
}
#endif

View File

@ -48,7 +48,6 @@ static const QString VERSION = "1.0.0";
SoundNotifyPlugin::SoundNotifyPlugin()
{
phonon.mo = NULL;
configured = false;
}
SoundNotifyPlugin::~SoundNotifyPlugin()
@ -72,13 +71,10 @@ bool SoundNotifyPlugin::initialize(const QStringList& args, QString *errMsg)
void SoundNotifyPlugin::extensionsInitialized()
{
Core::ICore::instance()->readSettings(this);
if ( !configured ){
readConfig_0_0_0();
}
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
connect(pm, SIGNAL(objectAdded(QObject*)), this, SLOT(onTelemetryManagerAdded(QObject*)));
removedNotifies.clear();
_toRemoveNotifications.clear();
connectNotifications();
}
@ -96,46 +92,19 @@ void SoundNotifyPlugin::saveConfig( QSettings* settings, UAVConfigInfo *configIn
settings->endGroup();
settings->beginWriteArray("listNotifies");
for (int i = 0; i < lstNotifications.size(); i++) {
for (int i = 0; i < _notificationList.size(); i++) {
settings->setArrayIndex(i);
lstNotifications.at(i)->saveState(settings);
_notificationList.at(i)->saveState(settings);
}
settings->endArray();
settings->setValue(QLatin1String("EnableSound"), enableSound);
}
void SoundNotifyPlugin::readConfig( QSettings* settings, UAVConfigInfo *configInfo){
if ( configInfo->version() == UAVConfigVersion() ){
// Just for migration to the new format.
configured = false;
return;
}
settings->beginReadArray("Current");
settings->setArrayIndex(0);
currentNotification.restoreState(settings);
settings->endArray();
// read list of notifications from settings
int size = settings->beginReadArray("listNotifies");
for (int i = 0; i < size; ++i) {
settings->setArrayIndex(i);
NotificationItem* notification = new NotificationItem;
notification->restoreState(settings);
lstNotifications.append(notification);
}
settings->endArray();
setEnableSound(settings->value(QLatin1String("EnableSound"),0).toBool());
configured = true;
}
void SoundNotifyPlugin::readConfig_0_0_0(){
settings = Core::ICore::instance()->settings();
settings->beginGroup(QLatin1String("NotifyPlugin"));
void SoundNotifyPlugin::readConfig( QSettings* settings, UAVConfigInfo *configInfo)
{
// Just for migration to the new format.
//Q_ASSERT(configInfo->version() == UAVConfigVersion());
settings->beginReadArray("Current");
settings->setArrayIndex(0);
@ -148,18 +117,10 @@ void SoundNotifyPlugin::readConfig_0_0_0(){
settings->setArrayIndex(i);
NotificationItem* notification = new NotificationItem;
notification->restoreState(settings);
lstNotifications.append(notification);
_notificationList.append(notification);
}
settings->endArray();
setEnableSound(settings->value(QLatin1String("EnableSound"),0).toBool());
settings->endGroup();
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
connect(pm, SIGNAL(objectAdded(QObject*)), this, SLOT(onTelemetryManagerAdded(QObject*)));
removedNotifies.clear();
connectNotifications();
configured = true;
}
void SoundNotifyPlugin::onTelemetryManagerAdded(QObject* obj)
@ -186,11 +147,11 @@ void SoundNotifyPlugin::onAutopilotDisconnect()
void SoundNotifyPlugin::resetNotification(void)
{
//first, reject empty args and unknown fields.
foreach(NotificationItem* ntf, lstNotifications) {
foreach(NotificationItem* ntf, _notificationList) {
ntf->disposeTimer();
disconnect(ntf->getTimer(), SIGNAL(timeout()), this, SLOT(repeatTimerHandler()));
disconnect(ntf->getTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
ntf->disposeExpireTimer();
disconnect(ntf->getExpireTimer(), SIGNAL(timeout()), this, SLOT(repeatTimerHandler()));
disconnect(ntf->getExpireTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
}
}
@ -200,10 +161,10 @@ void SoundNotifyPlugin::resetNotification(void)
*/
void SoundNotifyPlugin::updateNotificationList(QList<NotificationItem*> list)
{
removedNotifies.clear();
_toRemoveNotifications.clear();
resetNotification();
lstNotifications.clear();
lstNotifications=list;
_notificationList.clear();
_notificationList=list;
connectNotifications();
Core::ICore::instance()->saveSettings(this);
@ -213,7 +174,7 @@ void SoundNotifyPlugin::connectNotifications()
{
foreach(UAVDataObject* obj,lstNotifiedUAVObjects) {
if (obj != NULL)
disconnect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(appendNotification(UAVObject*)));
disconnect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(on_arrived_Notification(UAVObject*)));
}
if (phonon.mo != NULL) {
delete phonon.mo;
@ -226,29 +187,33 @@ void SoundNotifyPlugin::connectNotifications()
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
lstNotifiedUAVObjects.clear();
pendingNotifications.clear();
lstNotifications.append(removedNotifies);
removedNotifies.clear();
_pendingNotifications.clear();
_notificationList.append(_toRemoveNotifications);
_toRemoveNotifications.clear();
//first, reject empty args and unknown fields.
foreach(NotificationItem* notify, lstNotifications) {
notify->firstStart=true;
foreach(NotificationItem* notify, _notificationList) {
notify->_isPlayed = false;
notify->isNowPlaying=false;
if(notify->mute()) continue;
// check is all sounds presented for notification,
// if not - we must not subscribe to it at all
if(notify->toSoundList().isEmpty()) continue;
UAVDataObject* obj = dynamic_cast<UAVDataObject*>( objManager->getObject(notify->getDataObject()) );
if (obj != NULL ) {
if (!lstNotifiedUAVObjects.contains(obj)) {
lstNotifiedUAVObjects.append(obj);
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(appendNotification(UAVObject*)));
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(on_arrived_Notification(UAVObject*)));
}
} else {
qNotifyDebug() << "Error: Object is unknown (" << notify->getDataObject() << ").";
}
}
if (lstNotifications.isEmpty()) return;
if (_notificationList.isEmpty()) return;
// set notification message to current event
phonon.mo = Phonon::createPlayer(Phonon::NotificationCategory);
phonon.mo->clearQueue();
@ -262,138 +227,66 @@ void SoundNotifyPlugin::connectNotifications()
this, SLOT(stateChanged(Phonon::State,Phonon::State)));
}
void SoundNotifyPlugin::appendNotification(UAVObject *object)
void SoundNotifyPlugin::on_arrived_Notification(UAVObject *object)
{
disconnect(object, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(appendNotification(UAVObject*)));
foreach(NotificationItem* ntf, lstNotifications) {
foreach(NotificationItem* ntf, _notificationList) {
if (object->getName() != ntf->getDataObject())
continue;
if (nowPlayingConfiguration == ntf)
// skip duplicate notifications
if (_nowPlayingNotification == ntf)
continue;
// skip periodical notifications
// this condition accepts:
// 1. Periodical notifications played firstly;
// NOTE: At first time it will be played, then it played only by timer,
// when conditions became false firstStart flag has been cleared and
// notification can be accepted again;
// 2. Once time notifications, they removed immediately after first playing;
// 3. Instant notifications(played one by one without interval);
if (ntf->retryString() != "Repeat Instantly" &&
ntf->retryString() != "Repeat Once" && !ntf->firstStart)
ntf->retryString() != "Repeat Once" && ntf->_isPlayed)
continue;
checkNotificationRule(ntf,object);
qNotifyDebug() << QString("new notification: | %1 | %2 | val1: %3 | val2: %4")
.arg(ntf->getDataObject())
.arg(ntf->getObjectField())
.arg(ntf->singleValue().toString())
.arg(ntf->valueRange2());
QString fieldName = ntf->getObjectField();
UAVObjectField* field = object->getField(fieldName);
qNotifyDebug() << QString("UAV object: %1 | value: %2")
.arg(object->getName())
.arg(field->getValue().toString());
checkNotificationRule(ntf, object);
}
connect(object, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(appendNotification(UAVObject*)));
connect(object, SIGNAL(objectUpdated(UAVObject*)),
this, SLOT(on_arrived_Notification(UAVObject*)), Qt::UniqueConnection);
}
void SoundNotifyPlugin::checkNotificationRule(NotificationItem* notification, UAVObject* object)
{
bool condition=false;
double threshold;
QString direction;
QString fieldName;
threshold = notification->singleValue();
direction = notification->range();
fieldName = notification->getObjectField();
UAVObjectField* field = object->getField(fieldName);
if (field->getName().isEmpty())
return;
double value = field->getDouble();
switch(direction[0].toAscii())
{
case 'E':
condition = (value == threshold);
break;
case 'G':
condition = (value > threshold);
break;
case 'L':
condition = (value < threshold);
break;
case 'R':
condition = (value > threshold) && (value < notification->valueRange2());
break;
}
if (!condition)
return;
if (!playNotification(notification)) {
if (!pendingNotifications.contains(notification)) {
notification->stopTimer();
qNotifyDebug() << "add to pending list - " << notification->toString();
// if audio is busy, start expiration timer
//ms = (notification->getExpiredTimeout()[in sec])*1000
//QxtTimer::singleShot(notification->getExpireTimeout()*1000, this, SLOT(expirationTimerHandler(NotificationItem*)), qVariantFromValue(notification));
pendingNotifications.append(notification);
notification->startExpireTimer();
connect(notification->getExpireTimer(), SIGNAL(timeout()), this, SLOT(expireTimerHandler()));
}
}
}
bool SoundNotifyPlugin::playNotification(NotificationItem* notification)
{
// Check: race condition, if phonon.mo got deleted don't go further
if (phonon.mo == NULL)
return false;
if (notification->mute())
return false;
qNotifyDebug() << "Phonon State: " << phonon.mo->state();
if ((phonon.mo->state()==Phonon::PausedState)
|| (phonon.mo->state()==Phonon::StoppedState)
|| phonon.firstPlay)
{
// don't fire expire timer
nowPlayingConfiguration = notification;
notification->stopExpireTimer();
if (notification->retryString() == "Repeat Once") {
removedNotifies.append(lstNotifications.takeAt(lstNotifications.indexOf(notification)));
} else {
if (notification->retryString() != "Repeat Instantly") {
QRegExp rxlen("(\\d+)");
QString value;
int timer_value;
int pos = rxlen.indexIn(notification->retryString());
if (pos > -1) {
value = rxlen.cap(1); // "189"
timer_value = (value.toInt()+8)*1000; //ms*1000 + average duration of meassage
}
notification->startTimer(timer_value);
connect(notification->getTimer(), SIGNAL(timeout()), this, SLOT(repeatTimerHandler()));
}
}
notification->firstStart=false;
phonon.mo->clear();
qNotifyDebug() << "play notification - " << notification->toString();
foreach (QString item, notification->toSoundList()) {
Phonon::MediaSource *ms = new Phonon::MediaSource(item);
ms->setAutoDelete(true);
phonon.mo->enqueue(*ms);
}
phonon.mo->play();
phonon.firstPlay = false; // On Linux, you sometimes have to nudge Phonon to play 1 time before
// the state is not "Loading" anymore.
} else {
return false; // if audio is busy
}
return true;
}
void SoundNotifyPlugin::repeatTimerHandler()
void SoundNotifyPlugin::on_timerRepeated_Notification()
{
NotificationItem* notification = static_cast<NotificationItem*>(sender()->parent());
if (!notification)
return;
// skip duplicate notifications
// WARNING: generally we shoudn't ever trap here
// this means, that timer fires to early and notification overlap itself
if (_nowPlayingNotification == notification) {
qNotifyDebug() << "WARN: on_timerRepeated - notification was skipped!";
notification->restartTimer();
return;
}
qNotifyDebug() << "repeatTimerHandler - " << notification->toString();
qNotifyDebug() << QString("repeatTimer: %1% | %2 | %3").arg(notification->getDataObject())
.arg(notification->getObjectField())
.arg(notification->toString());
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
@ -402,15 +295,23 @@ void SoundNotifyPlugin::repeatTimerHandler()
checkNotificationRule(notification,object);
}
void SoundNotifyPlugin::expireTimerHandler()
void SoundNotifyPlugin::on_expiredTimer_Notification()
{
// fire expire timer
NotificationItem* notification = static_cast<NotificationItem*>(sender()->parent());
if(!notification)
return;
notification->stopExpireTimer();
if (!pendingNotifications.isEmpty()) {
qNotifyDebug() << "expireTimerHandler - " << notification->toString();
pendingNotifications.removeOne(notification);
volatile QMutexLocker lock(&_mutex);
if (!_pendingNotifications.isEmpty()) {
qNotifyDebug() << QString("expireTimer: %1% | %2 | %3").arg(notification->getDataObject())
.arg(notification->getObjectField())
.arg(notification->toString());
_pendingNotifications.removeOne(notification);
}
}
@ -418,8 +319,7 @@ void SoundNotifyPlugin::stateChanged(Phonon::State newstate, Phonon::State oldst
{
Q_UNUSED(oldstate)
qNotifyDebug() << "File length (ms): " << phonon.mo->totalTime();
qNotifyDebug() << "New State: " << newstate;
//qNotifyDebug() << "File length (ms): " << phonon.mo->totalTime();
#ifndef Q_OS_WIN
// This is a hack to force Linux to wait until the end of the
@ -432,11 +332,18 @@ void SoundNotifyPlugin::stateChanged(Phonon::State newstate, Phonon::State oldst
if ((newstate == Phonon::PausedState) ||
(newstate == Phonon::StoppedState))
{
nowPlayingConfiguration=NULL;
if (!pendingNotifications.isEmpty())
qNotifyDebug() << "New State: " << QVariant(newstate).toString();
volatile QMutexLocker lock(&_mutex);
// assignment to NULL needed to detect that palying is finished
// it's useful in repeat timer handler, where we can detect
// that notification has not overlap with itself
_nowPlayingNotification = NULL;
if (!_pendingNotifications.isEmpty())
{
NotificationItem* notification = pendingNotifications.takeFirst();
qNotifyDebug() << "play audioFree - " << notification->toString();
NotificationItem* notification = _pendingNotifications.takeFirst();
qNotifyDebug_if(notification) << "play audioFree - " << notification->toString();
playNotification(notification);
}
} else {
@ -449,4 +356,163 @@ void SoundNotifyPlugin::stateChanged(Phonon::State newstate, Phonon::State oldst
}
}
bool checkRange(QString fieldValue, QString enumValue, QStringList values, char direction)
{
bool ret = false;
switch(direction)
{
case 'E':
ret = !QString::compare(enumValue, fieldValue, Qt::CaseInsensitive) ? true : false;
break;
default:
ret = true;
break;
};
return ret;
}
bool checkRange(double fieldValue, double min, double max, char direction)
{
bool ret = false;
Q_ASSERT(min < max);
switch(direction)
{
case 'E':
ret = (fieldValue == min);
break;
case 'G':
ret = (fieldValue > min);
break;
case 'L':
ret = (fieldValue < min);
break;
default:
ret = (fieldValue > min) && (fieldValue < max);
break;
};
return ret;
}
void SoundNotifyPlugin::checkNotificationRule(NotificationItem* notification, UAVObject* object)
{
bool condition=false;
if (notification->mute())
return;
QString direction = notification->range();
QString fieldName = notification->getObjectField();
UAVObjectField* field = object->getField(fieldName);
if (field->getName().isEmpty())
return;
QVariant value = field->getValue();
if(UAVObjectField::ENUM == field->getType()) {
condition = checkRange(value.toString(),
notification->singleValue().toString(),
field->getOptions(),
direction[0].toAscii());
} else {
condition = checkRange(value.toDouble(),
notification->singleValue().toDouble(),
notification->valueRange2(),
direction[0].toAscii());
}
notification->_isPlayed = condition;
// if condition has been changed, and already in false state
// we should reset _isPlayed flag and stop repeat timer
if (!notification->_isPlayed) {
notification->stopTimer();
return;
}
volatile QMutexLocker lock(&_mutex);
if (!playNotification(notification)) {
if (!_pendingNotifications.contains(notification)
&& (_nowPlayingNotification != notification)) {
notification->stopTimer();
qNotifyDebug() << "add to pending list - " << notification->toString();
// if audio is busy, start expiration timer
//ms = (notification->getExpiredTimeout()[in sec])*1000
//QxtTimer::singleShot(notification->getExpireTimeout()*1000, this, SLOT(expirationTimerHandler(NotificationItem*)), qVariantFromValue(notification));
_pendingNotifications.append(notification);
notification->startExpireTimer();
connect(notification->getExpireTimer(), SIGNAL(timeout()),
this, SLOT(on_expiredTimer_Notification()), Qt::UniqueConnection);
}
}
}
bool SoundNotifyPlugin::playNotification(NotificationItem* notification)
{
if(!notification)
return false;
// Check: race condition, if phonon.mo got deleted don't go further
if (phonon.mo == NULL)
return false;
//qNotifyDebug() << "Phonon State: " << phonon.mo->state();
if ((phonon.mo->state()==Phonon::PausedState)
|| (phonon.mo->state()==Phonon::StoppedState)
|| phonon.firstPlay)
{
_nowPlayingNotification = notification;
notification->stopExpireTimer();
if (notification->retryString() == "Repeat Once") {
_toRemoveNotifications.append(_notificationList.takeAt(_notificationList.indexOf(notification)));
} else {
if (notification->retryString() != "Repeat Instantly") {
QRegExp rxlen("(\\d+)");
QString value;
int timer_value;
int pos = rxlen.indexIn(notification->retryString());
if (pos > -1) {
value = rxlen.cap(1); // "189"
// needs to correct repeat timer value,
// acording to message play duration,
// we don't measure duration of each message,
// simply take average duration
enum { eAverageDurationSec = 8 };
enum { eSecToMsec = 1000 };
timer_value = (value.toInt() + eAverageDurationSec) * eSecToMsec;
}
notification->startTimer(timer_value);
connect(notification->getTimer(), SIGNAL(timeout()),
this, SLOT(on_timerRepeated_Notification()), Qt::UniqueConnection);
}
}
phonon.mo->clear();
qNotifyDebug() << "play: " << notification->toString();
foreach (QString item, notification->toSoundList()) {
Phonon::MediaSource *ms = new Phonon::MediaSource(item);
ms->setAutoDelete(true);
phonon.mo->enqueue(*ms);
}
phonon.mo->play();
phonon.firstPlay = false; // On Linux, you sometimes have to nudge Phonon to play 1 time before
// the state is not "Loading" anymore.
return true;
}
return false;
}
Q_EXPORT_PLUGIN(SoundNotifyPlugin)

View File

@ -63,7 +63,7 @@ public:
void shutdown();
QList<NotificationItem*> getListNotifications() { return lstNotifications; }
QList<NotificationItem*> getListNotifications() { return _notificationList; }
NotificationItem* getCurrentNotification(){ return &currentNotification;}
bool getEnableSound() const { return enableSound; }
@ -83,14 +83,12 @@ private slots:
void connectNotifications();
void updateNotificationList(QList<NotificationItem*> list);
void resetNotification(void);
void appendNotification(UAVObject *object);
void repeatTimerHandler(void);
void expireTimerHandler(void);
void on_arrived_Notification(UAVObject *object);
void on_timerRepeated_Notification(void);
void on_expiredTimer_Notification(void);
void stateChanged(Phonon::State newstate, Phonon::State oldstate);
private:
bool configured; // just for migration,delete later
bool enableSound;
QList< QList<Phonon::MediaSource>* > lstMediaSource;
QStringList mediaSource;
@ -98,17 +96,17 @@ private:
QSettings* settings;
QList<UAVDataObject*> lstNotifiedUAVObjects;
QList<NotificationItem*> lstNotifications;
QList<NotificationItem*> pendingNotifications;
QList<NotificationItem*> removedNotifies;
QList<NotificationItem*> _notificationList;
QList<NotificationItem*> _pendingNotifications;
QList<NotificationItem*> _toRemoveNotifications;
NotificationItem currentNotification;
NotificationItem* nowPlayingConfiguration;
NotificationItem* _nowPlayingNotification;
QString m_field;
PhononObject phonon;
NotifyPluginOptionsPage *mop;
NotifyPluginOptionsPage* mop;
TelemetryManager* telMngr;
QMutex _mutex;
};
#endif // SOUNDNOTIFYPLUGIN_H

View File

@ -57,11 +57,10 @@ NotifyPluginOptionsPage::NotifyPluginOptionsPage(QObject *parent)
: IOptionsPage(parent)
, _objManager(*ExtensionSystem::PluginManager::instance()->getObject<UAVObjectManager>())
, _owner(qobject_cast<SoundNotifyPlugin*>(parent))
, _currentCollectionPath("")
, _valueRange(NULL)
, _dynamicFieldLimit(NULL)
, _dynamicFieldWidget(NULL)
, _dynamicFieldType(-1)
, _sayOrder(NULL)
, _fieldValue(NULL)
, _fieldType(-1)
, _form(NULL)
, _selectedNotification(NULL)
{}
@ -74,23 +73,21 @@ QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent)
_optionsPage.reset(new Ui::NotifyPluginOptionsPage());
//main widget
QWidget* optionsPageWidget = new QWidget;
_fieldValue = NULL;
_valueRange = NULL;
_dynamicFieldWidget = NULL;
_dynamicFieldLimit = NULL;
resetFieldType();
//save ref to form, needed for binding dynamic fields in future
_form = optionsPageWidget;
//main layout
_optionsPage->setupUi(optionsPageWidget);
_listSoundFiles.clear();
_optionsPage->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory);
_optionsPage->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory"));
connect(_optionsPage->SoundDirectoryPathChooser, SIGNAL(changed(const QString&)),
this, SLOT(on_buttonSoundFolder_clicked(const QString&)));
this, SLOT(on_clicked_buttonSoundFolder(const QString&)));
connect(_optionsPage->SoundCollectionList, SIGNAL(currentIndexChanged (int)),
this, SLOT(on_soundLanguage_indexChanged(int)));
this, SLOT(on_changedIndex_soundLanguage(int)));
connect(this, SIGNAL(updateNotifications(QList<NotificationItem*>)),
_owner, SLOT(updateNotificationList(QList<NotificationItem*>)));
@ -100,8 +97,8 @@ QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent)
// [1]
_selectedNotification = _owner->getCurrentNotification();
addDynamicValueLayout();
setSelectedNotification(_owner->getCurrentNotification());
addDynamicFieldLayout();
// [2]
updateConfigView(_selectedNotification);
@ -109,7 +106,8 @@ QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent)
initButtons();
initPhononPlayer();
_notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(0, 0, QModelIndex()),
int curr_row = _privListNotifications.indexOf(_selectedNotification);
_notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(curr_row, 0, QModelIndex()),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
return optionsPageWidget;
@ -125,151 +123,41 @@ void NotifyPluginOptionsPage::apply()
void NotifyPluginOptionsPage::finish()
{
disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_UAVField_indexChanged(QString)));
this, SLOT(on_changedIndex_UAVField(QString)));
disconnect(_notifySound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this,SLOT(on_changeButtonText(Phonon::State,Phonon::State)));
if (_notifySound) {
_notifySound->stop();
_notifySound->clear();
disconnect(_testSound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this,SLOT(on_changed_playButtonText(Phonon::State,Phonon::State)));
if (_testSound) {
_testSound->stop();
_testSound->clear();
}
}
void NotifyPluginOptionsPage::addDynamicValueLayout()
{
NotificationItem* curr = _owner->getCurrentNotification();
Q_ASSERT(curr);
_optionsPage->dynamicValueLayout->addWidget(new QLabel("Say order ", _form));
_sayOrder = new QComboBox(_form);
_optionsPage->dynamicValueLayout->addWidget(_sayOrder);
_sayOrder->addItems(NotificationItem::sayOrderValues);
_optionsPage->dynamicValueLayout->addWidget(new QLabel("Value is ", _form));
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(_objManager.getObject(curr->getDataObject()));
UAVObjectField* field = obj->getField(curr->getObjectField());
Q_ASSERT(obj);
Q_ASSERT(field);
_valueRange = new QComboBox(_form);
_optionsPage->dynamicValueLayout->addWidget(_valueRange);
addDynamicField(field);
}
void NotifyPluginOptionsPage::resetValueRange()
{
(static_cast<QLineEdit*>(_fieldValue))->setInputMask("999.99 - 999.99;");
(static_cast<QLineEdit*>(_fieldValue))->setText("0000000000");
(static_cast<QLineEdit*>(_fieldValue))->setCursorPosition(0);
}
void NotifyPluginOptionsPage::on_rangeValue_indexChanged(QString rangeStr)
{
Q_ASSERT(_fieldValue);
UAVObjectField* field = getObjectFieldFromPage();
Q_ASSERT(!!field);
setDynamicValueWidget(field);
setDynamicValueField(_selectedNotification);
}
void NotifyPluginOptionsPage::resetFieldType()
{
_fieldType = -1;
}
void NotifyPluginOptionsPage::addDynamicField(UAVObjectField* objField)
{
//qDebugNotify_ if (!objField || !parent) << "null input params";
Q_ASSERT(objField);
if (objField->getType() == _fieldType) {
if (QComboBox* fieldValue = dynamic_cast<QComboBox*>(_fieldValue)) {
fieldValue->clear();
QStringList enumValues(objField->getOptions());
fieldValue->addItems(enumValues);
}
return;
}
disconnect(_valueRange, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_rangeValue_indexChanged(QString)));
_valueRange->clear();
QStringList rangeValues;
if (UAVObjectField::ENUM == objField->getType()) {
rangeValues << cStrEqualTo << cStrInRange;
_valueRange->addItems(rangeValues);
_valueRange->setCurrentIndex(rangeValues.indexOf(_selectedNotification->range()));
} else {
rangeValues << cStrEqualTo << cStrLargeThan << cStrLowerThan << cStrInRange;
_valueRange->addItems(rangeValues);
connect(_valueRange, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_rangeValue_indexChanged(QString)));
}
setDynamicValueWidget(objField);
}
void NotifyPluginOptionsPage::setDynamicValueWidget(UAVObjectField* objField)
{
Q_ASSERT(_valueRange);
// check if dynamic fileld already settled,
// so if its exists remove it and install new field
if (_fieldValue) {
_optionsPage->dynamicValueLayout->removeWidget(_fieldValue);
delete _fieldValue;
_fieldValue = NULL;
}
_fieldType = objField->getType();
switch(_fieldType)
{
case UAVObjectField::ENUM:
{
_fieldValue = new QComboBox(_form);
QStringList enumValues(objField->getOptions());
(dynamic_cast<QComboBox*>(_fieldValue))->addItems(enumValues);
}
break;
default:
if (_valueRange->currentText() == cStrInRange) {
_fieldValue = new QLineEdit(_form);
resetValueRange();
} else {
_fieldValue = new QSpinBox(_form);
}
break;
};
_optionsPage->dynamicValueLayout->addWidget(_fieldValue);
}
void NotifyPluginOptionsPage::initButtons()
{
_optionsPage->chkEnableSound->setChecked(_owner->getEnableSound());
connect(_optionsPage->chkEnableSound, SIGNAL(toggled(bool)),
this, SLOT(on_checkEnableSound_toggled(bool)));
this, SLOT(on_toggled_checkEnableSound(bool)));
_optionsPage->buttonModify->setEnabled(false);
_optionsPage->buttonDelete->setEnabled(false);
_optionsPage->buttonPlayNotification->setEnabled(false);
connect(_optionsPage->buttonAdd, SIGNAL(pressed()),
this, SLOT(on_button_AddNotification_clicked()));
this, SLOT(on_clicked_buttonAddNotification()));
connect(_optionsPage->buttonDelete, SIGNAL(pressed()),
this, SLOT(on_button_DeleteNotification_clicked()));
this, SLOT(on_clicked_buttonDeleteNotification()));
connect(_optionsPage->buttonModify, SIGNAL(pressed()),
this, SLOT(on_button_ModifyNotification_clicked()));
this, SLOT(on_clicked_buttonModifyNotification()));
connect(_optionsPage->buttonPlayNotification, SIGNAL(clicked()),
this, SLOT(on_button_TestSoundNotification_clicked()));
this, SLOT(on_clicked_buttonTestSoundNotification()));
}
void NotifyPluginOptionsPage::initPhononPlayer()
{
_notifySound.reset(Phonon::createPlayer(Phonon::NotificationCategory));
connect(_notifySound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this,SLOT(on_changeButtonText(Phonon::State,Phonon::State)));
connect(_notifySound.data(), SIGNAL(finished(void)), this, SLOT(on_FinishedPlaying(void)));
_testSound.reset(Phonon::createPlayer(Phonon::NotificationCategory));
connect(_testSound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this,SLOT(on_changed_playButtonText(Phonon::State,Phonon::State)));
connect(_testSound.data(), SIGNAL(finished(void)), this, SLOT(on_FinishedPlaying(void)));
}
void NotifyPluginOptionsPage::initRulesTable()
@ -280,7 +168,7 @@ void NotifyPluginOptionsPage::initRulesTable()
_notifyRulesSelection = new QItemSelectionModel(_notifyRulesModel.data());
connect(_notifyRulesSelection, SIGNAL(selectionChanged ( const QItemSelection &, const QItemSelection & )),
this, SLOT(on_table_changeSelection( const QItemSelection & , const QItemSelection & )));
this, SLOT(on_changedSelection_notifyTable( const QItemSelection & , const QItemSelection & )));
connect(this, SIGNAL(entryUpdated(int)),
_notifyRulesModel.data(), SLOT(entryUpdated(int)));
@ -299,6 +187,159 @@ void NotifyPluginOptionsPage::initRulesTable()
_optionsPage->notifyRulesView->setDragDropMode(QAbstractItemView::InternalMove);
}
UAVObjectField* NotifyPluginOptionsPage::getObjectFieldFromSelected()
{
return (_currUAVObject) ? _currUAVObject->getField(_selectedNotification->getObjectField()) : NULL;
}
void NotifyPluginOptionsPage::setSelectedNotification(NotificationItem* ntf)
{
_selectedNotification = ntf;
_currUAVObject = dynamic_cast<UAVDataObject*>(_objManager.getObject(_selectedNotification->getDataObject()));
if(!_currUAVObject) {
qNotifyDebug() << "no such UAVObject: " << _selectedNotification->getDataObject();
}
}
void NotifyPluginOptionsPage::addDynamicFieldLayout()
{
// there is no need to check (objField == NULL),
// thus it doesn't use in this field directly
QSizePolicy labelSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
labelSizePolicy.setHorizontalStretch(0);
labelSizePolicy.setVerticalStretch(0);
// labelSizePolicy.setHeightForWidth(UAVObject->sizePolicy().hasHeightForWidth());
QLabel* labelSayOrder = new QLabel("Say order ", _form);
labelSayOrder->setSizePolicy(labelSizePolicy);
_optionsPage->dynamicValueLayout->addWidget(labelSayOrder);
_sayOrder = new QComboBox(_form);
_optionsPage->dynamicValueLayout->addWidget(_sayOrder);
_sayOrder->addItems(NotificationItem::sayOrderValues);
QLabel* labelValueIs = new QLabel("Value is ", _form);
labelValueIs->setSizePolicy(labelSizePolicy);
_optionsPage->dynamicValueLayout->addWidget(labelValueIs);
_dynamicFieldLimit = new QComboBox(_form);
_optionsPage->dynamicValueLayout->addWidget(_dynamicFieldLimit);
UAVObjectField* field = getObjectFieldFromSelected();
addDynamicField(field);
}
void NotifyPluginOptionsPage::addDynamicField(UAVObjectField* objField)
{
if(!objField) {
qNotifyDebug() << "addDynamicField | input objField == NULL";
return;
}
if (objField->getType() == _dynamicFieldType) {
if (QComboBox* fieldValue = dynamic_cast<QComboBox*>(_dynamicFieldWidget)) {
fieldValue->clear();
QStringList enumValues(objField->getOptions());
fieldValue->addItems(enumValues);
}
return;
}
disconnect(_dynamicFieldLimit, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_changedIndex_rangeValue(QString)));
_dynamicFieldLimit->clear();
QStringList rangeValues;
if (UAVObjectField::ENUM == objField->getType()) {
rangeValues << cStrEqualTo << cStrInRange;
_dynamicFieldLimit->addItems(rangeValues);
_dynamicFieldLimit->setCurrentIndex(rangeValues.indexOf(_selectedNotification->range()));
} else {
rangeValues << cStrEqualTo << cStrLargeThan << cStrLowerThan << cStrInRange;
_dynamicFieldLimit->addItems(rangeValues);
connect(_dynamicFieldLimit, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_changedIndex_rangeValue(QString)));
}
addDynamicFieldWidget(objField);
}
void NotifyPluginOptionsPage::addDynamicFieldWidget(UAVObjectField* objField)
{
if(!objField) {
qNotifyDebug() << "objField == NULL!";
return;
}
// check if dynamic fileld already settled,
// so if its exists remove it and install new field
if (_dynamicFieldWidget) {
_optionsPage->dynamicValueLayout->removeWidget(_dynamicFieldWidget);
delete _dynamicFieldWidget;
_dynamicFieldWidget = NULL;
}
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
_dynamicFieldType = objField->getType();
switch(_dynamicFieldType)
{
case UAVObjectField::ENUM:
{
_dynamicFieldWidget = new QComboBox(_form);
QStringList enumValues(objField->getOptions());
(dynamic_cast<QComboBox*>(_dynamicFieldWidget))->addItems(enumValues);
}
break;
default:
Q_ASSERT(_dynamicFieldLimit);
if (_dynamicFieldLimit->currentText() == cStrInRange) {
_dynamicFieldWidget = new QLineEdit(_form);
(static_cast<QLineEdit*>(_dynamicFieldWidget))->setInputMask("999.99 - 999.99;");
(static_cast<QLineEdit*>(_dynamicFieldWidget))->setText("0000000000");
(static_cast<QLineEdit*>(_dynamicFieldWidget))->setCursorPosition(0);
} else {
_dynamicFieldWidget = new QDoubleSpinBox(_form);
(dynamic_cast<QDoubleSpinBox*>(_dynamicFieldWidget))->setRange(000.00, 999.99);
}
break;
};
enum { eDynamicFieldWidth = 100 };
_dynamicFieldWidget->setSizePolicy(sizePolicy);
_dynamicFieldWidget->setFixedWidth(eDynamicFieldWidth);
_optionsPage->dynamicValueLayout->addWidget(_dynamicFieldWidget);
}
void NotifyPluginOptionsPage::setDynamicFieldValue(NotificationItem* notification)
{
if (QDoubleSpinBox* seValue = dynamic_cast<QDoubleSpinBox*>(_dynamicFieldWidget))
seValue->setValue(notification->singleValue().toDouble());
else {
if (QComboBox* cbValue = dynamic_cast<QComboBox*>(_dynamicFieldWidget)) {
int idx = cbValue->findText(notification->singleValue().toString());
if(-1 != idx)
cbValue->setCurrentIndex(idx);
} else {
if (QLineEdit* rangeValue = dynamic_cast<QLineEdit*>(_dynamicFieldWidget)) {
QString str = QString("%1%2").arg(notification->singleValue().toDouble(), 5, 'f', 2, '0')
.arg(notification->valueRange2(), 5, 'f', 2, '0');
rangeValue->setText(str);
} else {
qNotifyDebug() << "NotifyPluginOptionsPage::setDynamicValueField | unknown _fieldValue: " << _dynamicFieldWidget;
}
}
}
}
void NotifyPluginOptionsPage::resetFieldType()
{
_dynamicFieldType = -1;
}
void NotifyPluginOptionsPage::getOptionsPageValues(NotificationItem* notification)
{
Q_ASSERT(notification);
@ -310,14 +351,14 @@ void NotifyPluginOptionsPage::getOptionsPageValues(NotificationItem* notificatio
notification->setSound2(_optionsPage->Sound2->currentText());
notification->setSound3(_optionsPage->Sound3->currentText());
notification->setSayOrder(_sayOrder->currentText());
notification->setRange(_valueRange->currentText());
if (QSpinBox* spinValue = dynamic_cast<QSpinBox*>(_fieldValue))
notification->setRange(_dynamicFieldLimit->currentText());
if (QDoubleSpinBox* spinValue = dynamic_cast<QDoubleSpinBox*>(_dynamicFieldWidget))
notification->setSingleValue(spinValue->value());
else {
if (QComboBox* comboBoxValue = dynamic_cast<QComboBox*>(_fieldValue))
notification->setSingleValue(comboBoxValue->currentIndex());
if (QComboBox* comboBoxValue = dynamic_cast<QComboBox*>(_dynamicFieldWidget))
notification->setSingleValue(comboBoxValue->currentText());
else {
if (QLineEdit* rangeValue = dynamic_cast<QLineEdit*>(_fieldValue)) {
if (QLineEdit* rangeValue = dynamic_cast<QLineEdit*>(_dynamicFieldWidget)) {
QString str = rangeValue->text();
QStringList range = str.split('-');
notification->setSingleValue(range.at(0).toDouble());
@ -327,113 +368,13 @@ void NotifyPluginOptionsPage::getOptionsPageValues(NotificationItem* notificatio
}
}
void NotifyPluginOptionsPage::on_UAVField_indexChanged(QString field)
{
resetFieldType();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>( _objManager.getObject(_optionsPage->UAVObject->currentText()));
addDynamicField(obj->getField(field));
}
void NotifyPluginOptionsPage::on_UAVObject_indexChanged(QString val)
{
resetFieldType();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>( _objManager.getObject(val) );
QList<UAVObjectField*> fieldList = obj->getFields();
disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVField_indexChanged(QString)));
_optionsPage->UAVObjectField->clear();
foreach (UAVObjectField* field, fieldList) {
_optionsPage->UAVObjectField->addItem(field->getName());
}
connect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVField_indexChanged(QString)));
addDynamicField(fieldList.at(0));
}
void NotifyPluginOptionsPage::on_buttonSoundFolder_clicked(const QString& path)
{
QDir dirPath(path);
_listDirCollections = dirPath.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
_optionsPage->SoundCollectionList->clear();
_optionsPage->SoundCollectionList->addItems(_listDirCollections);
}
void NotifyPluginOptionsPage::on_soundLanguage_indexChanged(int index)
{
_optionsPage->SoundCollectionList->setCurrentIndex(index);
_currentCollectionPath = _optionsPage->SoundDirectoryPathChooser->path()
+ QDir::toNativeSeparators("/" + _optionsPage->SoundCollectionList->currentText());
QDir dirPath(_currentCollectionPath);
QStringList filters;
filters << "*.mp3" << "*.wav";
dirPath.setNameFilters(filters);
_listSoundFiles = dirPath.entryList(filters);
_listSoundFiles.replaceInStrings(QRegExp(".mp3|.wav"), "");
_optionsPage->Sound1->clear();
_optionsPage->Sound2->clear();
_optionsPage->Sound3->clear();
_optionsPage->Sound1->addItems(_listSoundFiles);
_optionsPage->Sound2->addItem("");
_optionsPage->Sound2->addItems(_listSoundFiles);
_optionsPage->Sound3->addItem("");
_optionsPage->Sound3->addItems(_listSoundFiles);
}
void NotifyPluginOptionsPage::on_changeButtonText(Phonon::State newstate, Phonon::State oldstate)
{
//Q_ASSERT(Phonon::ErrorState != newstate);
if (newstate == Phonon::PausedState || newstate == Phonon::StoppedState) {
_optionsPage->buttonPlayNotification->setText("Play");
_optionsPage->buttonPlayNotification->setIcon(QPixmap(":/notify/images/play.png"));
} else {
if (newstate == Phonon::PlayingState) {
_optionsPage->buttonPlayNotification->setText("Stop");
_optionsPage->buttonPlayNotification->setIcon(QPixmap(":/notify/images/stop.png"));
}
}
}
void NotifyPluginOptionsPage::on_FinishedPlaying()
{
_notifySound->clear();
}
void NotifyPluginOptionsPage::on_button_TestSoundNotification_clicked()
{
NotificationItem* notification = NULL;
qNotifyDebug() << "on_buttonTestSoundNotification_clicked";
Q_ASSERT(-1 != _notifyRulesSelection->currentIndex().row());
_notifySound->clearQueue();
notification = _privListNotifications.at(_notifyRulesSelection->currentIndex().row());
QStringList sequence = notification->toSoundList();
if (sequence.isEmpty()) {
qNotifyDebug() << "message sequense is empty!";
return;
}
foreach(QString item, sequence) {
qNotifyDebug() << item;
_notifySound->enqueue(Phonon::MediaSource(item));
}
_notifySound->play();
}
void NotifyPluginOptionsPage::on_checkEnableSound_toggled(bool state)
{
bool state1 = 1^state;
QList<Phonon::Path> listOutputs = _notifySound->outputPaths();
Phonon::AudioOutput * audioOutput = (Phonon::AudioOutput*)listOutputs.last().sink();
audioOutput->setMuted(state1);
}
void NotifyPluginOptionsPage::updateConfigView(NotificationItem* notification)
{
Q_ASSERT(notification);
disconnect(_optionsPage->UAVObject, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_UAVObject_indexChanged(QString)));
this, SLOT(on_changedIndex_UAVObject(QString)));
disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_UAVField_indexChanged(QString)));
this, SLOT(on_changedIndex_UAVField(QString)));
QString path = notification->getSoundCollectionPath();
if (path.isEmpty()) {
@ -461,13 +402,10 @@ void NotifyPluginOptionsPage::updateConfigView(NotificationItem* notification)
}
_optionsPage->UAVObjectField->clear();
QString uavDataObject = notification->getDataObject();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(_objManager.getObject(uavDataObject));
if (obj != NULL ) {
QList<UAVObjectField*> fieldList = obj->getFields();
foreach (UAVObjectField* field, fieldList) {
if(_currUAVObject) {
QList<UAVObjectField*> fieldList = _currUAVObject->getFields();
foreach (UAVObjectField* field, fieldList)
_optionsPage->UAVObjectField->addItem(field->getName());
}
}
if (-1 != _optionsPage->UAVObjectField->findText(notification->getObjectField())) {
@ -498,63 +436,105 @@ void NotifyPluginOptionsPage::updateConfigView(NotificationItem* notification)
_optionsPage->Sound3->setCurrentIndex(_optionsPage->Sound3->findText(notification->getSound3()));
}
if (-1 != _valueRange->findText(notification->range())) {
_valueRange->setCurrentIndex(_valueRange->findText(notification->range()));
if (-1 != _dynamicFieldLimit->findText(notification->range())) {
_dynamicFieldLimit->setCurrentIndex(_dynamicFieldLimit->findText(notification->range()));
}
if (-1 != _sayOrder->findText(notification->getSayOrder())) {
_sayOrder->setCurrentIndex(_sayOrder->findText(notification->getSayOrder()));
}
setDynamicValueField(notification);
setDynamicFieldValue(notification);
connect(_optionsPage->UAVObject, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_UAVObject_indexChanged(QString)));
this, SLOT(on_changedIndex_UAVObject(QString)));
connect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_UAVField_indexChanged(QString)));
this, SLOT(on_changedIndex_UAVField(QString)));
}
void NotifyPluginOptionsPage::setDynamicValueField(NotificationItem* notification)
void NotifyPluginOptionsPage::on_changedIndex_rangeValue(QString rangeStr)
{
if (QSpinBox* spinValue = dynamic_cast<QSpinBox*>(_fieldValue))
spinValue->setValue(notification->singleValue());
else {
if (QComboBox* comboBoxValue = dynamic_cast<QComboBox*>(_fieldValue))
comboBoxValue->setCurrentIndex(notification->singleValue());
else {
if (QLineEdit* rangeValue = dynamic_cast<QLineEdit*>(_fieldValue)) {
//resetValueRange();
QString str = QString("%1%2").arg(notification->singleValue(), 5, 'f', 2, '0')
.arg(notification->valueRange2(), 5, 'f', 2, '0');
rangeValue->setText(str);
} else {
qNotifyDebug() << "NotifyPluginOptionsPage::setDynamicValueField | unknown _fieldValue: " << _fieldValue;
}
Q_ASSERT(_dynamicFieldWidget);
UAVObjectField* field = getObjectFieldFromSelected();
Q_ASSERT(!!field);
addDynamicFieldWidget(field);
setDynamicFieldValue(_selectedNotification);
}
void NotifyPluginOptionsPage::on_changedIndex_UAVField(QString field)
{
resetFieldType();
Q_ASSERT(_currUAVObject);
addDynamicField(_currUAVObject->getField(field));
}
void NotifyPluginOptionsPage::on_changedIndex_UAVObject(QString val)
{
resetFieldType();
_currUAVObject = dynamic_cast<UAVDataObject*>( _objManager.getObject(val) );
if(!_currUAVObject) {
qNotifyDebug() << "on_UAVObject_indexChanged | no such UAVOBject";
return;
}
QList<UAVObjectField*> fieldList = _currUAVObject->getFields();
disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_changedIndex_UAVField(QString)));
_optionsPage->UAVObjectField->clear();
foreach (UAVObjectField* field, fieldList) {
_optionsPage->UAVObjectField->addItem(field->getName());
}
connect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_changedIndex_UAVField(QString)));
_selectedNotification->setObjectField(fieldList.at(0)->getName());
addDynamicField(fieldList.at(0));
}
void NotifyPluginOptionsPage::on_changedIndex_soundLanguage(int index)
{
_optionsPage->SoundCollectionList->setCurrentIndex(index);
QString collectionPath = _optionsPage->SoundDirectoryPathChooser->path()
+ QDir::toNativeSeparators("/" + _optionsPage->SoundCollectionList->currentText());
QDir dirPath(collectionPath);
QStringList filters;
filters << "*.mp3" << "*.wav";
dirPath.setNameFilters(filters);
QStringList listSoundFiles = dirPath.entryList(filters);
listSoundFiles.replaceInStrings(QRegExp(".mp3|.wav"), "");
_optionsPage->Sound1->clear();
_optionsPage->Sound2->clear();
_optionsPage->Sound3->clear();
_optionsPage->Sound1->addItems(listSoundFiles);
_optionsPage->Sound2->addItem("");
_optionsPage->Sound2->addItems(listSoundFiles);
_optionsPage->Sound3->addItem("");
_optionsPage->Sound3->addItems(listSoundFiles);
}
void NotifyPluginOptionsPage::on_changed_playButtonText(Phonon::State newstate, Phonon::State oldstate)
{
//Q_ASSERT(Phonon::ErrorState != newstate);
if (newstate == Phonon::PausedState || newstate == Phonon::StoppedState) {
_optionsPage->buttonPlayNotification->setText("Play");
_optionsPage->buttonPlayNotification->setIcon(QPixmap(":/notify/images/play.png"));
} else {
if (newstate == Phonon::PlayingState) {
_optionsPage->buttonPlayNotification->setText("Stop");
_optionsPage->buttonPlayNotification->setIcon(QPixmap(":/notify/images/stop.png"));
}
}
}
UAVObjectField* NotifyPluginOptionsPage::getObjectFieldFromPage()
{
UAVDataObject* obj = dynamic_cast<UAVDataObject*>( _objManager.getObject(_optionsPage->UAVObject->currentText()));
return obj->getField(_optionsPage->UAVObjectField->currentText());
}
UAVObjectField* NotifyPluginOptionsPage::getObjectFieldFromSelected()
{
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(_objManager.getObject(_selectedNotification->getDataObject()));
return obj->getField(_selectedNotification->getObjectField());
}
void NotifyPluginOptionsPage::on_table_changeSelection( const QItemSelection & selected, const QItemSelection & deselected )
void NotifyPluginOptionsPage::on_changedSelection_notifyTable(const QItemSelection & selected, const QItemSelection & deselected )
{
bool select = false;
_notifySound->stop();
_testSound->stop();
if (selected.indexes().size()) {
select = true;
_selectedNotification = _privListNotifications.at(selected.indexes().at(0).row());
setSelectedNotification(_privListNotifications.at(selected.indexes().at(0).row()));
UAVObjectField* field = getObjectFieldFromSelected();
addDynamicField(field);
updateConfigView(_selectedNotification);
@ -565,7 +545,34 @@ void NotifyPluginOptionsPage::on_table_changeSelection( const QItemSelection & s
_optionsPage->buttonPlayNotification->setEnabled(select);
}
void NotifyPluginOptionsPage::on_button_AddNotification_clicked()
void NotifyPluginOptionsPage::on_clicked_buttonSoundFolder(const QString& path)
{
QDir dirPath(path);
QStringList listDirCollections = dirPath.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
_optionsPage->SoundCollectionList->clear();
_optionsPage->SoundCollectionList->addItems(listDirCollections);
}
void NotifyPluginOptionsPage::on_clicked_buttonTestSoundNotification()
{
NotificationItem* notification = NULL;
qNotifyDebug() << "on_buttonTestSoundNotification_clicked";
Q_ASSERT(-1 != _notifyRulesSelection->currentIndex().row());
_testSound->clearQueue();
notification = _privListNotifications.at(_notifyRulesSelection->currentIndex().row());
QStringList sequence = notification->toSoundList();
if (sequence.isEmpty()) {
qNotifyDebug() << "message sequense is empty!";
return;
}
foreach(QString item, sequence) {
qNotifyDebug() << item;
_testSound->enqueue(Phonon::MediaSource(item));
}
_testSound->play();
}
void NotifyPluginOptionsPage::on_clicked_buttonAddNotification()
{
NotificationItem* notification = new NotificationItem;
@ -574,27 +581,15 @@ void NotifyPluginOptionsPage::on_button_AddNotification_clicked()
textPalette.setColor(QPalette::Normal,QPalette::Text, Qt::red);
_optionsPage->SoundDirectoryPathChooser->setPalette(textPalette);
_optionsPage->SoundDirectoryPathChooser->setPath("please select sound collection folder");
delete notification;
return;
}
getOptionsPageValues(notification);
notification->setSoundCollectionPath(_optionsPage->SoundDirectoryPathChooser->path());
notification->setCurrentLanguage(_optionsPage->SoundCollectionList->currentText());
notification->setDataObject(_optionsPage->UAVObject->currentText());
notification->setObjectField(_optionsPage->UAVObjectField->currentText());
notification->setRange(_valueRange->currentText());
if (QSpinBox* spinValue = dynamic_cast<QSpinBox*>(_fieldValue))
notification->setSingleValue(spinValue->value());
if (_optionsPage->Sound1->currentText().size() > 0)
notification->setSound1(_optionsPage->Sound1->currentText());
notification->setSound2(_optionsPage->Sound2->currentText());
notification->setSound3(_optionsPage->Sound3->currentText());
if ( ((!_optionsPage->Sound2->currentText().size()) && (_sayOrder->currentText()=="After second"))
|| ((!_optionsPage->Sound3->currentText().size()) && (_sayOrder->currentText()=="After third")) ) {
return;
if ( ((!_optionsPage->Sound2->currentText().isEmpty()) && (_sayOrder->currentText()=="After second"))
|| ((!_optionsPage->Sound3->currentText().isEmpty()) && (_sayOrder->currentText()=="After third")) ) {
delete notification;
return;
} else {
notification->setSayOrder(_sayOrder->currentText());
}
@ -604,7 +599,7 @@ void NotifyPluginOptionsPage::on_button_AddNotification_clicked()
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
}
void NotifyPluginOptionsPage::on_button_DeleteNotification_clicked()
void NotifyPluginOptionsPage::on_clicked_buttonDeleteNotification()
{
_notifyRulesModel->removeRow(_notifyRulesSelection->currentIndex().row());
if (!_notifyRulesModel->rowCount()
@ -617,7 +612,7 @@ void NotifyPluginOptionsPage::on_button_DeleteNotification_clicked()
}
}
void NotifyPluginOptionsPage::on_button_ModifyNotification_clicked()
void NotifyPluginOptionsPage::on_clicked_buttonModifyNotification()
{
NotificationItem* notification = new NotificationItem;
getOptionsPageValues(notification);
@ -628,3 +623,17 @@ void NotifyPluginOptionsPage::on_button_ModifyNotification_clicked()
_privListNotifications.replace(_notifyRulesSelection->currentIndex().row(),notification);
entryUpdated(_notifyRulesSelection->currentIndex().row());
}
void NotifyPluginOptionsPage::on_FinishedPlaying()
{
_testSound->clear();
}
void NotifyPluginOptionsPage::on_toggled_checkEnableSound(bool state)
{
bool state1 = 1^state;
QList<Phonon::Path> listOutputs = _testSound->outputPaths();
Phonon::AudioOutput * audioOutput = (Phonon::AudioOutput*)listOutputs.last().sink();
audioOutput->setMuted(state1);
}

View File

@ -73,33 +73,28 @@ public:
void finish();
void restoreFromSettings();
void updateConfigView(NotificationItem* notification);
void getOptionsPageValues(NotificationItem* notification);
UAVObjectField* getObjectFieldFromPage();
UAVObjectField* getObjectFieldFromSelected();
signals:
void updateNotifications(QList<NotificationItem*> list);
void entryUpdated(int index);
private slots:
void on_button_TestSoundNotification_clicked();
void on_button_AddNotification_clicked();
void on_button_DeleteNotification_clicked();
void on_button_ModifyNotification_clicked();
void on_clicked_buttonTestSoundNotification();
void on_clicked_buttonAddNotification();
void on_clicked_buttonDeleteNotification();
void on_clicked_buttonModifyNotification();
/**
* We can use continuous selection, to select simultaneously
* multiple rows to move them(using drag & drop) inside table ranges.
*/
void on_table_changeSelection( const QItemSelection & selected, const QItemSelection & deselected );
void on_changedSelection_notifyTable( const QItemSelection & selected, const QItemSelection & deselected );
void on_soundLanguage_indexChanged(int index);
void on_buttonSoundFolder_clicked(const QString& path);
void on_UAVObject_indexChanged(QString val);
void on_UAVField_indexChanged(QString val);
void on_changeButtonText(Phonon::State newstate, Phonon::State oldstate);
void on_checkEnableSound_toggled(bool state);
void on_changedIndex_soundLanguage(int index);
void on_clicked_buttonSoundFolder(const QString& path);
void on_changedIndex_UAVObject(QString val);
void on_changedIndex_UAVField(QString val);
void on_changed_playButtonText(Phonon::State newstate, Phonon::State oldstate);
void on_toggled_checkEnableSound(bool state);
/**
* Important when we change to or from "In range" value
@ -107,7 +102,7 @@ private slots:
* we need to change UI to show edit line,
* to have possibility assign range limits for value.
*/
void on_rangeValue_indexChanged(QString);
void on_changedIndex_rangeValue(QString);
void on_FinishedPlaying(void);
@ -115,29 +110,31 @@ private slots:
private:
Q_DISABLE_COPY(NotifyPluginOptionsPage)
void resetValueRange();
void resetFieldType();
void setDynamicValueField(NotificationItem* notification);
void addDynamicField(UAVObjectField* objField);
void addDynamicValueLayout();
void setDynamicValueWidget(UAVObjectField* objField);
void initButtons();
void initPhononPlayer();
void initRulesTable();
void setSelectedNotification(NotificationItem* ntf);
void resetValueRange();
void resetFieldType();
void updateConfigView(NotificationItem* notification);
void getOptionsPageValues(NotificationItem* notification);
UAVObjectField* getObjectFieldFromPage();
UAVObjectField* getObjectFieldFromSelected();
void addDynamicFieldLayout();
void addDynamicField(UAVObjectField* objField);
void addDynamicFieldWidget(UAVObjectField* objField);
void setDynamicFieldValue(NotificationItem* notification);
private:
UAVObjectManager& _objManager;
SoundNotifyPlugin* _owner;
QStringList _listDirCollections;
QStringList _listSoundFiles;
QString _currentCollectionPath;
Phonon::MediaObject* _sound1;
Phonon::MediaObject* _sound2;
QScopedPointer<Phonon::MediaObject> _notifySound;
Phonon::AudioOutput* _audioOutput;
//! Media object uses to test sound playing
QScopedPointer<Phonon::MediaObject> _testSound;
QScopedPointer<NotifyTableModel> _notifyRulesModel;
QItemSelectionModel* _notifyRulesSelection;
@ -154,34 +151,36 @@ private:
QScopedPointer<Ui::NotifyPluginOptionsPage> _optionsPage;
//! widget to convinient selection of condition for field value (equal, lower, greater)
QComboBox* _valueRange;
//! Widget to convinient selection of condition for field value (equal, lower, greater)
QComboBox* _dynamicFieldLimit;
//! widget to convinient selection of order in which sounds will be played
//! Represents edit widget for dynamic UAVObjectfield,
//! can be spinbox - for numerics, combobox - enums, or
//! lineedit - for numerics with range constraints
QWidget* _dynamicFieldWidget;
//! Type of UAVObjectField - numeric or ENUM,
//! this variable needs to correctly set appropriate dynamic UI element (_dynamicFieldWidget)
//! NOTE: ocassionaly it should be invalidated (= -1) to reset _dynamicFieldWidget
int _dynamicFieldType;
//! Widget to convinient selection of position of <dynamic field value>
//! between sounds[1..3]
QComboBox* _sayOrder;
//! widget to represent edit widget for UAVObjectfield,
//! can be spinbox - for numerics, combobox - enums, or
//! lineedit - for range limits
QWidget* _fieldValue;
//! type of UAVObjectField - numeric or ENUM
//! this variable needs to correctly set dynamic UI elemen _fieldValue
//! NOTE: ocassionaly it should be invalidated (= -1) to reset _fieldValue
int _fieldType;
//! actualy reference to optionsPageWidget,
//! Actualy reference to optionsPageWidget,
//! we MUST hold it beyond the scope of createPage func
//! to have possibility change dynamic parts of options page layout in future
QWidget* _form;
//! needs to correctly update UI during transitions from "In Range" to other
//! _valueRange entries and back direction as well
QString _prevRangeValue;
//! Currently selected notification, all controls filled accroding to it.
//! On options page startup, always points to first row.
NotificationItem* _selectedNotification;
//! Retrieved from UAVObjectManager by name from _selectedNotification,
//! if UAVObjectManager doesn't have such object, this field will be NULL
UAVDataObject* _currUAVObject;
};
#endif // NOTIFYPLUGINOPTIONSPAGE_H

View File

@ -45,19 +45,19 @@ bool NotifyTableModel::setData(const QModelIndex &index,
const QVariant &value, int role)
{
if (index.isValid() && role == Qt::DisplayRole) {
if(eMessageName == index.column()) {
if (eMessageName == index.column()) {
emit dataChanged(index, index);
return true;
}
}
if (index.isValid() && role == Qt::EditRole) {
if(eRepeatValue == index.column())
if (eRepeatValue == index.column())
_list.at(index.row())->setRetryString(value.toString());
else {
if(eExpireTimer == index.column())
if (eExpireTimer == index.column())
_list.at(index.row())->setLifetime(value.toInt());
else {
if(eTurnOn == index.column())
if (eTurnOn == index.column())
_list.at(index.row())->setMute(value.toBool());
}
}
@ -114,7 +114,7 @@ QVariant NotifyTableModel::headerData(int section, Qt::Orientation orientation,
if (orientation == Qt::Horizontal)
return _headerStrings.at(section);
else
if(orientation == Qt::Vertical)
if (orientation == Qt::Vertical)
return QString("%1").arg(section);
return QVariant();
@ -141,7 +141,7 @@ bool NotifyTableModel::removeRows(int position, int rows, const QModelIndex& ind
{
Q_UNUSED(index);
if((-1 == position) || (-1 == rows) )
if ((-1 == position) || (-1 == rows) )
return false;
beginRemoveRows(QModelIndex(), position, position + rows - 1);
@ -201,7 +201,7 @@ bool NotifyTableModel::dropMimeData( const QMimeData * data, Qt::DropAction acti
beginRow = rowCount(QModelIndex());
}
if(-1 == beginRow)
if (-1 == beginRow)
return false;
QByteArray encodedData = data->data(mime_type_notify_table);
@ -217,15 +217,18 @@ bool NotifyTableModel::dropMimeData( const QMimeData * data, Qt::DropAction acti
// or from bottom rows to top rows (UP_DIRECTION)
enum { UP_DIRECTION, DOWN_DIRECTION };
int direction = (dragged < rows) ? DOWN_DIRECTION : (dragged += 1, UP_DIRECTION);
Q_ASSERT(insertRows(rows + direction, 1, QModelIndex()));
if(-1 == dragged || rows >= _list.size() || dragged == rows) {
// check drop bounds
if (dragged < 0 || ((dragged + 1) >= _list.size() && direction == DOWN_DIRECTION) || dragged == rows) {
qNotifyDebug() << "no such item";
return false;
continue;
}
// addiional check in case dropping of multiple rows
if(rows + direction > _list.size()) continue;
Q_ASSERT(insertRows(rows + direction, 1, QModelIndex()));
_list.replace(rows + direction, item);
Q_ASSERT(removeRows(dragged, 1, QModelIndex()));
if(direction == UP_DIRECTION)
if (direction == UP_DIRECTION)
++rows;
};