diff --git a/ground/openpilotgcs/src/plugins/notify/NotificationItem.h b/ground/openpilotgcs/src/plugins/notify/NotificationItem.h index 20de7a4f8..1898f1a55 100644 --- a/ground/openpilotgcs/src/plugins/notify/NotificationItem.h +++ b/ground/openpilotgcs/src/plugins/notify/NotificationItem.h @@ -103,7 +103,31 @@ public: void seriaize(QDataStream& stream); void deseriaize(QDataStream& stream); - QString parseNotifyMessage(); + /** + * Convert notification item fields in single string, + * to show in table for example + * + * @return string which describe notification + */ + QString toString(); + + /** + * Generate list of sound files needed to play notification + * + * @return success - reference to non-empty _messageSequence; + * error - if one of sounds doesn't exist returns + * reference to empty _messageSequence; + */ + QStringList& toSoundList(); + + /** + * Returns sound caption name, needed to create string representation of notification. + * + * @return success - string == , if sound file exists + * error - string == [missind], if sound file doesn't exist + */ + QString getSoundCaption(QString fileName); + QTimer* getTimer() const { return _timer; } void startTimer(int value); @@ -119,10 +143,14 @@ public: bool isNowPlaying; bool firstStart; -private: - void checkSoundFilesExisting(bool& missed1, bool& missed2, bool& missed3); + static QStringList sayOrderValues; + static QStringList retryValues; private: + QString checkSoundExists(QString fileName); + +private: + QTimer* _timer; //! time from putting notification in queue till moment when notification became out-of-date @@ -130,6 +158,7 @@ private: //! according to its priority QTimer* _expireTimer; + //! list of wav files from which notification consists QStringList _messageSequence; //! path to folder with sound files diff --git a/ground/openpilotgcs/src/plugins/notify/notificationitem.cpp b/ground/openpilotgcs/src/plugins/notify/notificationitem.cpp index d6c803b68..1b0e634a6 100644 --- a/ground/openpilotgcs/src/plugins/notify/notificationitem.cpp +++ b/ground/openpilotgcs/src/plugins/notify/notificationitem.cpp @@ -40,10 +40,28 @@ #include "notifylogging.h" +static const QString cStrNever("Never"); +static const QString cStrBefore1st("Before first"); +static const QString cStrBefore2nd("Before second"); +static const QString cStrAfter2nd("After second"); + +static const QString cStrRetryOnce("Repeat Once"); +static const QString cStrRetryInstantly("Repeat Instantly"); +static const QString cStrRetry10sec("Repeat 10 seconds"); +static const QString cStrRetry30sec("Repeat 30 seconds"); +static const QString cStrRetry1min("Repeat 1 minute"); + + +QStringList NotificationItem::sayOrderValues; +QStringList NotificationItem::retryValues; + + NotificationItem::NotificationItem(QObject *parent) : QObject(parent) , isNowPlaying(0) , firstStart(true) + , _timer(NULL) + , _expireTimer(NULL) , _soundCollectionPath("") , _currentLanguage("default") , _dataObject("") @@ -52,16 +70,23 @@ NotificationItem::NotificationItem(QObject *parent) , _sound1("") , _sound2("") , _sound3("") - , _sayOrder("Never") + , _sayOrder(cStrNever) , _singleValue(0) , _valueRange2(0) - , _repeatString("Repeat Instantly") + , _repeatString(cStrRetryInstantly) , _expireTimeout(eDefaultTimeout) , _mute(false) - { - _timer = NULL; - _expireTimer = NULL; + NotificationItem::sayOrderValues.append(cStrBefore1st); + NotificationItem::sayOrderValues.append(cStrBefore2nd); + NotificationItem::sayOrderValues.append(cStrAfter2nd); + + NotificationItem::retryValues.append(cStrRetryOnce); + NotificationItem::retryValues.append(cStrRetryInstantly); + NotificationItem::retryValues.append(cStrRetry10sec); + NotificationItem::retryValues.append(cStrRetry30sec); + NotificationItem::retryValues.append(cStrRetry1min); + } void NotificationItem::copyTo(NotificationItem* that) const @@ -103,7 +128,6 @@ void NotificationItem::saveState(QSettings* settings) const settings->setValue(QLatin1String("Repeat"), retryString()); settings->setValue(QLatin1String("ExpireTimeout"), lifetime()); settings->setValue(QLatin1String("Mute"), mute()); - } void NotificationItem::restoreState(QSettings* settings) @@ -123,7 +147,6 @@ void NotificationItem::restoreState(QSettings* settings) setRetryString(settings->value(QLatin1String("Repeat"), tr("")).toString()); setLifetime(settings->value(QLatin1String("ExpireTimeout"), tr("")).toInt()); setMute(settings->value(QLatin1String("Mute"), tr("")).toInt()); - } void NotificationItem::seriaize(QDataStream& stream) @@ -162,7 +185,8 @@ void NotificationItem::deseriaize(QDataStream& stream) stream >> this->_mute; } -void NotificationItem::startTimer(int value) { +void NotificationItem::startTimer(int value) +{ if (!_timer) { _timer = new QTimer(this); _timer->setInterval(value); @@ -171,14 +195,16 @@ void NotificationItem::startTimer(int value) { _timer->start(); } -void NotificationItem::stopTimer() { +void NotificationItem::stopTimer() +{ if (_timer) { if (_timer->isActive()) _timer->stop(); } } -void NotificationItem::disposeTimer() { +void NotificationItem::disposeTimer() +{ if (_timer) { _timer->stop(); delete _timer; @@ -186,22 +212,24 @@ void NotificationItem::disposeTimer() { } } -void NotificationItem::startExpireTimer() { - if (!_expireTimer) - { +void NotificationItem::startExpireTimer() +{ + if (!_expireTimer) { _expireTimer = new QTimer(this); } _expireTimer->start(_expireTimeout * 1000); } -void NotificationItem::stopExpireTimer() { +void NotificationItem::stopExpireTimer() +{ if (_expireTimer) { if (_expireTimer) _expireTimer->stop(); } } -void NotificationItem::disposeExpireTimer() { +void NotificationItem::disposeExpireTimer() +{ if (_expireTimer) { _expireTimer->stop(); delete _expireTimer; @@ -209,91 +237,33 @@ void NotificationItem::disposeExpireTimer() { } } -#define missed "missed sound" -#define CHECK_ADD_SOUND(n) ((!_missedSound##n) ? getSound##n() : (missed#n)) -#define CHECK_REPLACE_SOUND(n) ((!_missedSound##n) ? str.replace(missed#n, getSound##n()) : (missed#n)) - -QString NotificationItem::parseNotifyMessage() +int getValuePosition(QString sayOrder) { - // tips: - // check of *.wav files exist needed for playing phonon queues; - // if phonon player don't find next file in queue, it buzz + return NotificationItem::sayOrderValues.indexOf(sayOrder); +} - QString str; - QString value; - QString sayOrder = getSayOrder(); - UAVObjectField* field = getUAVObjectField(); - if (UAVObjectField::ENUM == field->getType()) { - Q_ASSERT(singleValue() < field->getOptions().size()); - value = QString("%L1").arg(field->getOptions().at(singleValue())); - } else { - value = QString("%L1").arg(singleValue()); +QString NotificationItem::checkSoundExists(QString fileName) +{ + QString name(fileName + ".wav"); + QString filePath = QDir::toNativeSeparators(getSoundCollectionPath() + "/" + + getCurrentLanguage() + "/" + + name); + if(QFile::exists(filePath)) + return filePath; + else { + filePath = QDir::toNativeSeparators(getSoundCollectionPath() + + "/default/" + + name); + if(!QFile::exists(filePath)) + filePath.clear(); } + return filePath; +} - int position = -1; // default don't play value wav file - - // generate queue of sound files to play - _messageSequence.clear(); - - bool _missedSound1 = false; - bool _missedSound2 = false; - bool _missedSound3 = false; - - checkSoundFilesExisting(_missedSound1, _missedSound2, _missedSound3); - str = CHECK_ADD_SOUND(1)+" "+CHECK_ADD_SOUND(2)+" "+CHECK_ADD_SOUND(3); - - if(!_messageSequence.size()) { - qNotifyDebug() << "no any files in message queue"; - } - - sayOrder = sayOrder.trimmed(); - switch(sayOrder.at(0).toUpper().toAscii()) - { - case 'B'://BEFORE: - CHECK_REPLACE_SOUND(1); - CHECK_REPLACE_SOUND(2); - CHECK_REPLACE_SOUND(3); - str.prepend(value + " "); - position = 0; - break; - - case 'A'://AFTER: - switch(sayOrder.at(6).toLower().toAscii()) - { - case 'f': - str = CHECK_ADD_SOUND(1)+" "+value+" "+CHECK_ADD_SOUND(2)+" "+CHECK_ADD_SOUND(3); - position = 1; - break; - - case 's': - str = CHECK_ADD_SOUND(1)+" "+CHECK_ADD_SOUND(2)+" "+value+" "+CHECK_ADD_SOUND(3); - position = 2; - break; - - case 't': - CHECK_REPLACE_SOUND(1); - CHECK_REPLACE_SOUND(2); - CHECK_REPLACE_SOUND(3); - str.append(" "+value); - position = 3; - break; - } - break; - - default: - CHECK_REPLACE_SOUND(1); - CHECK_REPLACE_SOUND(2); - CHECK_REPLACE_SOUND(3); - break; - } - - if(-1 == position) { - qNotifyDebug() << "NotificationItem::parseNotifyMessage() | value position undefined"; - return str; - } - - if (UAVObjectField::ENUM == field->getType()) return str; - +QStringList valueToSoundList(QString value) +{ + // replace point chr if exists + value = value.replace(',', '.'); QStringList numberParts = value.trimmed().split("."); QStringList digitWavs; @@ -338,23 +308,100 @@ QString NotificationItem::parseNotifyMessage() digitWavs.append(numberParts.at(1).right(1)); } } - foreach(QString fileName, digitWavs) { - fileName+=".wav"; - QString filePath = QDir::toNativeSeparators(getSoundCollectionPath()+"/"+ getCurrentLanguage()+"/"+fileName); - if(QFile::exists(filePath)) - _messageSequence.insert(position++,QDir::toNativeSeparators(getSoundCollectionPath()+ "/"+getCurrentLanguage()+"/"+fileName)); - else { - if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+fileName))) - _messageSequence.insert(position++,QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+fileName)); - else { - _messageSequence.clear(); - break; // if no some of *.wav files, then don't play number! - } + return digitWavs; +} + +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()); + } + + int pos = getValuePosition(getSayOrder().trimmed()); + QStringList lst; + lst.append(getSoundCaption(getSound1())); + lst.append(getSoundCaption(getSound2())); + lst.append(getSoundCaption(getSound3())); + QStringList valueSounds = valueToSoundList(value); + bool missed = false; + foreach(QString sound, valueSounds) { + if(checkSoundExists(sound).isEmpty()) { + missed = true; + break; } } + + // if not "Never" case + if(-1 != pos) { + if(missed) + lst.insert(pos, "[missed]" + value); + else + lst.insert(pos, value); + } + str = lst.join(" "); return str; } +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()); + } + + // generate queue of sound files to play + _messageSequence.clear(); + int pos = getValuePosition(getSayOrder().trimmed()); + QStringList lst; + if(!getSound1().isEmpty()) + lst.append(getSound1()); + if(!getSound2().isEmpty()) + lst.append(getSound2()); + if(!getSound3().isEmpty()) + lst.append(getSound3()); + + // if not "Never" case + if(-1 != pos) { + QStringList valueSounds = valueToSoundList(value); + foreach(QString sound, valueSounds) + lst.insert(pos++, sound); + } + + foreach(QString sound, lst) { + QString path = checkSoundExists(sound); + if (!path.isEmpty()) { + _messageSequence.append(path); + } else { + _messageSequence.clear(); + break; + } + } + return _messageSequence; +} + +QString NotificationItem::getSoundCaption(QString fileName) +{ + if(fileName.isEmpty()) return QString(); + if(checkSoundExists(fileName).isEmpty()) { + return QString("[missed]") + fileName; + } + return fileName; +} + UAVObjectField* NotificationItem::getUAVObjectField() { return getUAVObject()->getField(getObjectField()); } @@ -362,39 +409,3 @@ UAVObjectField* NotificationItem::getUAVObjectField() { UAVDataObject* NotificationItem::getUAVObject() { return dynamic_cast((ExtensionSystem::PluginManager::instance()->getObject())->getObject(getDataObject())); } - - -void NotificationItem::checkSoundFilesExisting(bool& missed1, bool& missed2, bool& missed3) -{ - - if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound1()+".wav"))) - _messageSequence.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound1()+".wav")); - else { - if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound1()+".wav"))) - _messageSequence.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound1()+".wav")); - else - missed1 = true; - } - - if(getSound2().size()) { - if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound2()+".wav"))) - _messageSequence.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound2()+".wav")); - else { - if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound2()+".wav"))) - _messageSequence.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound2()+".wav")); - else - missed2 = true; - } - } - - if(getSound3().size()) { - if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath()+ "/" + getCurrentLanguage()+"/"+getSound3()+".wav"))) - _messageSequence.append(QDir::toNativeSeparators(getSoundCollectionPath()+ "/" + getCurrentLanguage()+"/"+getSound3()+".wav")); - else { - if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+getSound3()+".wav"))) - _messageSequence.append(QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+getSound3()+".wav")); - else - missed3 = true; - } - } -} diff --git a/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.cpp b/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.cpp index d418f0d26..da7177b35 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.cpp +++ b/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.cpp @@ -29,34 +29,29 @@ #include "notifyitemdelegate.h" #include "notifytablemodel.h" #include "notifylogging.h" +#include "notificationitem.h" NotifyItemDelegate::NotifyItemDelegate(QObject* parent) : QItemDelegate(parent) , _parent(parent) { - _titles << "Repeat Once" - << "Repeat Instantly" - << "Repeat 10 seconds" - << "Repeat 30 seconds" - << "Repeat 1 minute"; - } QWidget *NotifyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& /*none*/, const QModelIndex& index) const { - if (eREPEAT_VALUE == index.column()) { + if (eRepeatValue == index.column()) { QComboBox* editor = new QComboBox(parent); editor->clear(); - editor->addItems(_titles); + editor->addItems(NotificationItem::retryValues); return editor; } else { - if (eEXPIRE_TIME == index.column()) { + if (eExpireTimer == index.column()) { QSpinBox* editor = new QSpinBox(parent); connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); return editor; } else { - if (eENABLE_NOTIFICATION == index.column()) { + if (eTurnOn == index.column()) { QCheckBox* editor = new QCheckBox(parent); connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); return editor; diff --git a/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.h b/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.h index 494e61c17..ace6d4976 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.h +++ b/ground/openpilotgcs/src/plugins/notify/notifyitemdelegate.h @@ -34,25 +34,23 @@ class NotifyItemDelegate : public QItemDelegate { - Q_OBJECT + Q_OBJECT public: - NotifyItemDelegate(QObject *parent = 0); - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, - const QModelIndex &index) const; - void setEditorData(QWidget *editor, const QModelIndex &index) const; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const; - QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; + NotifyItemDelegate(QObject *parent = 0); + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, + const QModelIndex &index) const; + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; private slots: - void selectRow(const QString & text); - void commitAndCloseEditor(); + void selectRow(const QString & text); + void commitAndCloseEditor(); private: - QObject* _parent; - QStringList _titles; - + QObject* _parent; }; #endif // NOTIFYITEMDELEGATE_H diff --git a/ground/openpilotgcs/src/plugins/notify/notifyplugin.cpp b/ground/openpilotgcs/src/plugins/notify/notifyplugin.cpp index fa55cfc42..88cb23621 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifyplugin.cpp +++ b/ground/openpilotgcs/src/plugins/notify/notifyplugin.cpp @@ -49,7 +49,6 @@ SoundNotifyPlugin::SoundNotifyPlugin() { phonon.mo = NULL; configured = false; - // Do nothing } SoundNotifyPlugin::~SoundNotifyPlugin() @@ -57,7 +56,6 @@ SoundNotifyPlugin::~SoundNotifyPlugin() Core::ICore::instance()->saveSettings(this); if (phonon.mo != NULL) delete phonon.mo; - // Do nothing } bool SoundNotifyPlugin::initialize(const QStringList& args, QString *errMsg) @@ -99,8 +97,8 @@ void SoundNotifyPlugin::saveConfig( QSettings* settings, UAVConfigInfo *configIn settings->beginWriteArray("listNotifies"); for (int i = 0; i < lstNotifications.size(); i++) { - settings->setArrayIndex(i); - lstNotifications.at(i)->saveState(settings); + settings->setArrayIndex(i); + lstNotifications.at(i)->saveState(settings); } settings->endArray(); settings->setValue(QLatin1String("EnableSound"), enableSound); @@ -147,10 +145,10 @@ void SoundNotifyPlugin::readConfig_0_0_0(){ // 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->setArrayIndex(i); + NotificationItem* notification = new NotificationItem; + notification->restoreState(settings); + lstNotifications.append(notification); } settings->endArray(); setEnableSound(settings->value(QLatin1String("EnableSound"),0).toBool()); @@ -237,14 +235,17 @@ void SoundNotifyPlugin::connectNotifications() notify->firstStart=true; notify->isNowPlaying=false; + if(notify->mute()) continue; + UAVDataObject* obj = dynamic_cast( objManager->getObject(notify->getDataObject()) ); if (obj != NULL ) { if (!lstNotifiedUAVObjects.contains(obj)) { - lstNotifiedUAVObjects.append(obj); - connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(appendNotification(UAVObject*))); + lstNotifiedUAVObjects.append(obj); + connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(appendNotification(UAVObject*))); } - } else - std::cout << "Error: Object is unknown (" << notify->getDataObject().toStdString() << ")." << std::endl; + } else { + qNotifyDebug() << "Error: Object is unknown (" << notify->getDataObject() << ")."; + } } if (lstNotifications.isEmpty()) return; @@ -294,7 +295,7 @@ void SoundNotifyPlugin::checkNotificationRule(NotificationItem* notification, UA fieldName = notification->getObjectField(); UAVObjectField* field = object->getField(fieldName); - if (field->getName() == "") + if (field->getName().isEmpty()) return; double value = field->getDouble(); @@ -321,13 +322,11 @@ void SoundNotifyPlugin::checkNotificationRule(NotificationItem* notification, UA if (!condition) return; - if (!playNotification(notification)) - { - if (!pendingNotifications.contains(notification)) - { + if (!playNotification(notification)) { + if (!pendingNotifications.contains(notification)) { notification->stopTimer(); - qNotifyDebug() << "add to pending list - " << notification->parseNotifyMessage(); + 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)); @@ -344,8 +343,8 @@ bool SoundNotifyPlugin::playNotification(NotificationItem* notification) if (phonon.mo == NULL) return false; - if (!notification->mute()) - return true; + if (notification->mute()) + return false; qNotifyDebug() << "Phonon State: " << phonon.mo->state(); if ((phonon.mo->state()==Phonon::PausedState) @@ -375,9 +374,8 @@ bool SoundNotifyPlugin::playNotification(NotificationItem* notification) } notification->firstStart=false; phonon.mo->clear(); - QString str = notification->parseNotifyMessage(); - qNotifyDebug() << "play notification - " << str; - foreach (QString item, notification->getMessageSequence()) { + qNotifyDebug() << "play notification - " << notification->toString(); + foreach (QString item, notification->toSoundList()) { Phonon::MediaSource *ms = new Phonon::MediaSource(item); ms->setAutoDelete(true); phonon.mo->enqueue(*ms); @@ -393,15 +391,15 @@ bool SoundNotifyPlugin::playNotification(NotificationItem* notification) void SoundNotifyPlugin::repeatTimerHandler() { - NotificationItem* notification = static_cast(sender()->parent()); + NotificationItem* notification = static_cast(sender()->parent()); - qNotifyDebug() << "repeatTimerHandler - " << notification->parseNotifyMessage(); + qNotifyDebug() << "repeatTimerHandler - " << notification->toString(); - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager *objManager = pm->getObject(); - UAVObject* object = objManager->getObject(notification->getDataObject()); - if (object) - checkNotificationRule(notification,object); + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectManager *objManager = pm->getObject(); + UAVObject* object = objManager->getObject(notification->getDataObject()); + if (object) + checkNotificationRule(notification,object); } void SoundNotifyPlugin::expireTimerHandler() @@ -411,7 +409,7 @@ void SoundNotifyPlugin::expireTimerHandler() notification->stopExpireTimer(); if (!pendingNotifications.isEmpty()) { - qNotifyDebug() << "expireTimerHandler - " << notification->parseNotifyMessage(); + qNotifyDebug() << "expireTimerHandler - " << notification->toString(); pendingNotifications.removeOne(notification); } } @@ -438,7 +436,7 @@ void SoundNotifyPlugin::stateChanged(Phonon::State newstate, Phonon::State oldst if (!pendingNotifications.isEmpty()) { NotificationItem* notification = pendingNotifications.takeFirst(); - qNotifyDebug() << "play audioFree - " << notification->parseNotifyMessage(); + qNotifyDebug() << "play audioFree - " << notification->toString(); playNotification(notification); } } else { diff --git a/ground/openpilotgcs/src/plugins/notify/notifyplugin.h b/ground/openpilotgcs/src/plugins/notify/notifyplugin.h index 1d9475469..0b7a31f3b 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifyplugin.h +++ b/ground/openpilotgcs/src/plugins/notify/notifyplugin.h @@ -50,65 +50,65 @@ typedef struct { class SoundNotifyPlugin : public Core::IConfigurablePlugin -{ - Q_OBJECT -public: - SoundNotifyPlugin(); - ~SoundNotifyPlugin(); +{ + Q_OBJECT +public: + SoundNotifyPlugin(); + ~SoundNotifyPlugin(); - void extensionsInitialized(); - bool initialize(const QStringList & arguments, QString * errorString); - void readConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo); - void saveConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo); - void shutdown(); + void extensionsInitialized(); + bool initialize(const QStringList & arguments, QString * errorString); + void readConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo); + void saveConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo); + void shutdown(); - QList getListNotifications() { return lstNotifications; } - NotificationItem* getCurrentNotification(){ return ¤tNotification;} + QList getListNotifications() { return lstNotifications; } + NotificationItem* getCurrentNotification(){ return ¤tNotification;} - bool getEnableSound() const { return enableSound; } - void setEnableSound(bool value) {enableSound = value; } + bool getEnableSound() const { return enableSound; } + void setEnableSound(bool value) {enableSound = value; } private: - SoundNotifyPlugin(const SoundNotifyPlugin& rhs); - SoundNotifyPlugin& operator= (const SoundNotifyPlugin& rhs); + Q_DISABLE_COPY(SoundNotifyPlugin) - bool playNotification(NotificationItem* notification); - void checkNotificationRule(NotificationItem* notification, UAVObject* object); - void readConfig_0_0_0(); + bool playNotification(NotificationItem* notification); + void checkNotificationRule(NotificationItem* notification, UAVObject* object); + void readConfig_0_0_0(); private slots: - void onTelemetryManagerAdded(QObject* obj); - void onAutopilotDisconnect(); - void connectNotifications(); - void updateNotificationList(QList list); - void resetNotification(void); - void appendNotification(UAVObject *object); - void repeatTimerHandler(void); - void expireTimerHandler(void); - void stateChanged(Phonon::State newstate, Phonon::State oldstate); + + void onTelemetryManagerAdded(QObject* obj); + void onAutopilotDisconnect(); + void connectNotifications(); + void updateNotificationList(QList list); + void resetNotification(void); + void appendNotification(UAVObject *object); + void repeatTimerHandler(void); + void expireTimerHandler(void); + void stateChanged(Phonon::State newstate, Phonon::State oldstate); private: - bool configured; // just for migration,delete later - bool enableSound; - QList< QList* > lstMediaSource; - QStringList mediaSource; - QMultiMap mapMediaObjects; - QSettings* settings; + bool configured; // just for migration,delete later + bool enableSound; + QList< QList* > lstMediaSource; + QStringList mediaSource; + QMultiMap mapMediaObjects; + QSettings* settings; - QList lstNotifiedUAVObjects; - QList lstNotifications; - QList pendingNotifications; - QList removedNotifies; + QList lstNotifiedUAVObjects; + QList lstNotifications; + QList pendingNotifications; + QList removedNotifies; - NotificationItem currentNotification; - NotificationItem* nowPlayingConfiguration; + NotificationItem currentNotification; + NotificationItem* nowPlayingConfiguration; - QString m_field; - PhononObject phonon; - NotifyPluginOptionsPage *mop; - TelemetryManager* telMngr; + QString m_field; + PhononObject phonon; + NotifyPluginOptionsPage *mop; + TelemetryManager* telMngr; }; #endif // SOUNDNOTIFYPLUGIN_H diff --git a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.cpp b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.cpp index 305e5e13e..fdf0f5cc9 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.cpp +++ b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.cpp @@ -47,72 +47,61 @@ #include "notifytablemodel.h" #include "notifylogging.h" - -static const char* cStrBefore1st = "Before first"; -static const char* cStrBefore2nd = "Before second"; -static const char* cStrAfter2nd = "After second"; - static const char* cStrEqualTo = "Equal to"; static const char* cStrLargeThan = "Large than"; static const char* cStrLowerThan = "Lower than"; static const char* cStrInRange = "In range"; -//----------------------------------------------------------------------------- -NotifyPluginOptionsPage::NotifyPluginOptionsPage(/*NotificationItem *config,*/ QObject *parent) +NotifyPluginOptionsPage::NotifyPluginOptionsPage(QObject *parent) : IOptionsPage(parent) - , objManager(*ExtensionSystem::PluginManager::instance()->getObject()) - , owner(qobject_cast(parent)) - , currentCollectionPath("") + , _objManager(*ExtensionSystem::PluginManager::instance()->getObject()) + , _owner(qobject_cast(parent)) + , _currentCollectionPath("") , _valueRange(NULL) , _sayOrder(NULL) , _fieldValue(NULL) , _fieldType(-1) , _form(NULL) -{ -} + , _selectedNotification(NULL) +{} -//----------------------------------------------------------------------------- NotifyPluginOptionsPage::~NotifyPluginOptionsPage() -{ -} +{} -//creates options page widget (uses the UI file) - -//----------------------------------------------------------------------------- QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent) { - options_page.reset(new Ui::NotifyPluginOptionsPage()); + _optionsPage.reset(new Ui::NotifyPluginOptionsPage()); //main widget QWidget* optionsPageWidget = new QWidget; - //if(!_fieldValue.isNull()) _fieldValue = NULL; _valueRange = NULL; - _fieldType = -1; + resetFieldType(); //save ref to form, needed for binding dynamic fields in future _form = optionsPageWidget; //main layout - options_page->setupUi(optionsPageWidget); + _optionsPage->setupUi(optionsPageWidget); - listSoundFiles.clear(); - - options_page->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory); - options_page->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory")); - - connect(options_page->SoundDirectoryPathChooser, SIGNAL(changed(const QString&)), this, SLOT(on_buttonSoundFolder_clicked(const QString&))); - connect(options_page->SoundCollectionList, SIGNAL(currentIndexChanged (int)), this, SLOT(on_soundLanguage_indexChanged(int))); + _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&))); + connect(_optionsPage->SoundCollectionList, SIGNAL(currentIndexChanged (int)), + this, SLOT(on_soundLanguage_indexChanged(int))); connect(this, SIGNAL(updateNotifications(QList)), - owner, SLOT(updateNotificationList(QList))); + _owner, SLOT(updateNotificationList(QList))); //connect(this, SIGNAL(resetNotification()),owner, SLOT(resetNotification())); - privListNotifications = owner->getListNotifications(); + _privListNotifications = _owner->getListNotifications(); + // [1] + _selectedNotification = _owner->getCurrentNotification(); addDynamicValueLayout(); - _selectedNotification = owner->getCurrentNotification(); // [2] updateConfigView(_selectedNotification); @@ -120,117 +109,119 @@ QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent) initButtons(); initPhononPlayer(); -// _notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(0, 0, QModelIndex()), -// QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + _notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(0, 0, QModelIndex()), + QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); return optionsPageWidget; } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::apply() { - getOptionsPageValues(owner->getCurrentNotification()); - owner->setEnableSound(options_page->chkEnableSound->isChecked()); - emit updateNotifications(privListNotifications); + getOptionsPageValues(_owner->getCurrentNotification()); + _owner->setEnableSound(_optionsPage->chkEnableSound->isChecked()); + emit updateNotifications(_privListNotifications); } void NotifyPluginOptionsPage::finish() { + disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), + this, SLOT(on_UAVField_indexChanged(QString))); - disconnect(options_page->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(onUAVField_indexChanged(QString))); - - disconnect(notifySound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)), - this,SLOT(changeButtonText(Phonon::State,Phonon::State))); - if (notifySound) { - notifySound->stop(); - notifySound->clear(); + disconnect(_notifySound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)), + this,SLOT(on_changeButtonText(Phonon::State,Phonon::State))); + if (_notifySound) { + _notifySound->stop(); + _notifySound->clear(); } } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::addDynamicValueLayout() { - NotificationItem* curr = owner->getCurrentNotification(); + NotificationItem* curr = _owner->getCurrentNotification(); Q_ASSERT(curr); - options_page->dynamicValueLayout->addWidget(new QLabel("Say order ", _form)); + _optionsPage->dynamicValueLayout->addWidget(new QLabel("Say order ", _form)); _sayOrder = new QComboBox(_form); - options_page->dynamicValueLayout->addWidget(_sayOrder); - QStringList sayOrderValues; - sayOrderValues << cStrBefore1st << cStrBefore2nd << cStrAfter2nd; - _sayOrder->addItems(sayOrderValues); + _optionsPage->dynamicValueLayout->addWidget(_sayOrder); + _sayOrder->addItems(NotificationItem::sayOrderValues); - options_page->dynamicValueLayout->addWidget(new QLabel("Value is ", _form)); + _optionsPage->dynamicValueLayout->addWidget(new QLabel("Value is ", _form)); - UAVDataObject* obj = dynamic_cast(objManager.getObject(curr->getDataObject())); + UAVDataObject* obj = dynamic_cast(_objManager.getObject(curr->getDataObject())); UAVObjectField* field = obj->getField(curr->getObjectField()); Q_ASSERT(obj); Q_ASSERT(field); _valueRange = new QComboBox(_form); - options_page->dynamicValueLayout->addWidget(_valueRange); + _optionsPage->dynamicValueLayout->addWidget(_valueRange); addDynamicField(field); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::resetValueRange() { - _fieldValue = new QLineEdit(_form); (static_cast(_fieldValue))->setInputMask("999.99 - 999.99;"); (static_cast(_fieldValue))->setText("0000000000"); (static_cast(_fieldValue))->setCursorPosition(0); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::on_rangeValue_indexChanged(QString rangeStr) { Q_ASSERT(_fieldValue); - if(rangeStr == cStrInRange) { - Q_ASSERT(_fieldValue); - options_page->dynamicValueLayout->removeWidget(_fieldValue); - resetValueRange(); - options_page->dynamicValueLayout->addWidget(_fieldValue); - - // _fieldType = -1; - // addDynamicField(field); - } + 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"; + //qDebugNotify_ if (!objField || !parent) << "null input params"; Q_ASSERT(objField); - if(objField->getType() == _fieldType) { - if(QComboBox* fieldValue = dynamic_cast(_fieldValue)) { + if (objField->getType() == _fieldType) { + if (QComboBox* fieldValue = dynamic_cast(_fieldValue)) { fieldValue->clear(); QStringList enumValues(objField->getOptions()); fieldValue->addItems(enumValues); } return; } - // check if dynamic fileld already settled, - // so if its exists remove it and install new field - if(_fieldValue) - options_page->dynamicValueLayout->removeWidget(_fieldValue); disconnect(_valueRange, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_rangeValue_indexChanged(QString))); _valueRange->clear(); QStringList rangeValues; - if(UAVObjectField::ENUM == objField->getType()) { + if (UAVObjectField::ENUM == objField->getType()) { rangeValues << cStrEqualTo << cStrInRange; _valueRange->addItems(rangeValues); - } - else { + _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) { @@ -243,92 +234,90 @@ void NotifyPluginOptionsPage::addDynamicField(UAVObjectField* objField) break; default: - if(_valueRange->currentText() == cStrInRange) { + if (_valueRange->currentText() == cStrInRange) { + _fieldValue = new QLineEdit(_form); resetValueRange(); } else { _fieldValue = new QSpinBox(_form); } break; }; - options_page->dynamicValueLayout->addWidget(_fieldValue); + _optionsPage->dynamicValueLayout->addWidget(_fieldValue); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::initButtons() { - options_page->chkEnableSound->setChecked(owner->getEnableSound()); - connect(options_page->chkEnableSound, SIGNAL(toggled(bool)), this, SLOT(on_chkEnableSound_toggled(bool))); + _optionsPage->chkEnableSound->setChecked(_owner->getEnableSound()); + connect(_optionsPage->chkEnableSound, SIGNAL(toggled(bool)), + this, SLOT(on_checkEnableSound_toggled(bool))); - options_page->buttonModify->setEnabled(false); - options_page->buttonDelete->setEnabled(false); - options_page->buttonPlayNotification->setEnabled(false); - connect(options_page->buttonAdd, SIGNAL(pressed()), this, SLOT(on_buttonAddNotification_clicked())); - connect(options_page->buttonDelete, SIGNAL(pressed()), this, SLOT(on_buttonDeleteNotification_clicked())); - connect(options_page->buttonModify, SIGNAL(pressed()), this, SLOT(on_buttonModifyNotification_clicked())); - connect(options_page->buttonPlayNotification, SIGNAL(clicked()), this, SLOT(on_buttonTestSoundNotification_clicked())); + _optionsPage->buttonModify->setEnabled(false); + _optionsPage->buttonDelete->setEnabled(false); + _optionsPage->buttonPlayNotification->setEnabled(false); + connect(_optionsPage->buttonAdd, SIGNAL(pressed()), + this, SLOT(on_button_AddNotification_clicked())); + connect(_optionsPage->buttonDelete, SIGNAL(pressed()), + this, SLOT(on_button_DeleteNotification_clicked())); + connect(_optionsPage->buttonModify, SIGNAL(pressed()), + this, SLOT(on_button_ModifyNotification_clicked())); + connect(_optionsPage->buttonPlayNotification, SIGNAL(clicked()), + this, SLOT(on_button_TestSoundNotification_clicked())); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::initPhononPlayer() { - notifySound.reset(Phonon::createPlayer(Phonon::NotificationCategory)); - connect(notifySound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)), - this,SLOT(changeButtonText(Phonon::State,Phonon::State))); - connect(notifySound.data(), SIGNAL(finished(void)), this, SLOT(onFinishedPlaying(void))); + _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))); } - -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::initRulesTable() { qNotifyDebug_if(_notifyRulesModel.isNull()) << "_notifyRulesModel.isNull())"; qNotifyDebug_if(!_notifyRulesSelection) << "_notifyRulesSelection.isNull())"; - //QItemSelectionModel* selection = _notifyRulesSelection.take(); - _notifyRulesModel.reset(new NotifyTableModel(privListNotifications)); + _notifyRulesModel.reset(new NotifyTableModel(_privListNotifications)); _notifyRulesSelection = new QItemSelectionModel(_notifyRulesModel.data()); connect(_notifyRulesSelection, SIGNAL(selectionChanged ( const QItemSelection &, const QItemSelection & )), - this, SLOT(on_tableNotification_changeSelection( const QItemSelection & , const QItemSelection & ))); + this, SLOT(on_table_changeSelection( const QItemSelection & , const QItemSelection & ))); connect(this, SIGNAL(entryUpdated(int)), - _notifyRulesModel.data(), SLOT(entryUpdated(int))); -// connect(this, SIGNAL(entryAdded(int)), -// _notifyRulesModel.data(), SLOT(entryAdded(int))); + _notifyRulesModel.data(), SLOT(entryUpdated(int))); - options_page->notifyRulesView->setModel(_notifyRulesModel.data()); - options_page->notifyRulesView->setSelectionModel(_notifyRulesSelection); - options_page->notifyRulesView->setItemDelegate(new NotifyItemDelegate(this)); + _optionsPage->notifyRulesView->setModel(_notifyRulesModel.data()); + _optionsPage->notifyRulesView->setSelectionModel(_notifyRulesSelection); + _optionsPage->notifyRulesView->setItemDelegate(new NotifyItemDelegate(this)); - options_page->notifyRulesView->resizeRowsToContents(); - options_page->notifyRulesView->setColumnWidth(eMESSAGE_NAME,200); - options_page->notifyRulesView->setColumnWidth(eREPEAT_VALUE,120); - options_page->notifyRulesView->setColumnWidth(eEXPIRE_TIME,100); - options_page->notifyRulesView->setColumnWidth(eENABLE_NOTIFICATION,60); - options_page->notifyRulesView->setDragEnabled(true); - options_page->notifyRulesView->setAcceptDrops(true); - options_page->notifyRulesView->setDropIndicatorShown(true); - options_page->notifyRulesView->setDragDropMode(QAbstractItemView::InternalMove); + _optionsPage->notifyRulesView->resizeRowsToContents(); + _optionsPage->notifyRulesView->setColumnWidth(eMessageName,200); + _optionsPage->notifyRulesView->setColumnWidth(eRepeatValue,120); + _optionsPage->notifyRulesView->setColumnWidth(eExpireTimer,100); + _optionsPage->notifyRulesView->setColumnWidth(eTurnOn,60); + _optionsPage->notifyRulesView->setDragEnabled(true); + _optionsPage->notifyRulesView->setAcceptDrops(true); + _optionsPage->notifyRulesView->setDropIndicatorShown(true); + _optionsPage->notifyRulesView->setDragDropMode(QAbstractItemView::InternalMove); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::getOptionsPageValues(NotificationItem* notification) { Q_ASSERT(notification); - notification->setSoundCollectionPath(options_page->SoundDirectoryPathChooser->path()); - notification->setCurrentLanguage(options_page->SoundCollectionList->currentText()); - notification->setDataObject(options_page->UAVObject->currentText()); - notification->setObjectField(options_page->UAVObjectField->currentText()); - notification->setSound1(options_page->Sound1->currentText()); - notification->setSound2(options_page->Sound2->currentText()); - notification->setSound3(options_page->Sound3->currentText()); + notification->setSoundCollectionPath(_optionsPage->SoundDirectoryPathChooser->path()); + notification->setCurrentLanguage(_optionsPage->SoundCollectionList->currentText()); + notification->setDataObject(_optionsPage->UAVObject->currentText()); + notification->setObjectField(_optionsPage->UAVObjectField->currentText()); + notification->setSound1(_optionsPage->Sound1->currentText()); + notification->setSound2(_optionsPage->Sound2->currentText()); + notification->setSound3(_optionsPage->Sound3->currentText()); notification->setSayOrder(_sayOrder->currentText()); notification->setRange(_valueRange->currentText()); - if(QSpinBox* spinValue = dynamic_cast(_fieldValue)) + if (QSpinBox* spinValue = dynamic_cast(_fieldValue)) notification->setSingleValue(spinValue->value()); else { - if(QComboBox* comboBoxValue = dynamic_cast(_fieldValue)) + if (QComboBox* comboBoxValue = dynamic_cast(_fieldValue)) notification->setSingleValue(comboBoxValue->currentIndex()); else { - if(QLineEdit* rangeValue = dynamic_cast(_fieldValue)) { + if (QLineEdit* rangeValue = dynamic_cast(_fieldValue)) { QString str = rangeValue->text(); QStringList range = str.split('-'); notification->setSingleValue(range.at(0).toDouble()); @@ -338,190 +327,175 @@ void NotifyPluginOptionsPage::getOptionsPageValues(NotificationItem* notificatio } } - -//----------------------------------------------------------------------------- -void NotifyPluginOptionsPage::onUAVField_indexChanged(QString field) { - _fieldType = -1; - UAVDataObject* obj = dynamic_cast( objManager.getObject(options_page->UAVObject->currentText())); +void NotifyPluginOptionsPage::on_UAVField_indexChanged(QString field) +{ + resetFieldType(); + UAVDataObject* obj = dynamic_cast( _objManager.getObject(_optionsPage->UAVObject->currentText())); addDynamicField(obj->getField(field)); } -////////////////////////////////////////////////////////////////////////////// -// Fills in the combo box when value is changed in the -// combo box -////////////////////////////////////////////////////////////////////////////// -void NotifyPluginOptionsPage::on_UAVObject_indexChanged(QString val) { - _fieldType = -1; - UAVDataObject* obj = dynamic_cast( objManager.getObject(val) ); +void NotifyPluginOptionsPage::on_UAVObject_indexChanged(QString val) +{ + resetFieldType(); + UAVDataObject* obj = dynamic_cast( _objManager.getObject(val) ); QList fieldList = obj->getFields(); - disconnect(options_page->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(onUAVField_indexChanged(QString))); - options_page->UAVObjectField->clear(); + disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVField_indexChanged(QString))); + _optionsPage->UAVObjectField->clear(); foreach (UAVObjectField* field, fieldList) { - options_page->UAVObjectField->addItem(field->getName()); + _optionsPage->UAVObjectField->addItem(field->getName()); } - connect(options_page->UAVObjectField, SIGNAL(currentIndexChanged(QString)), this, SLOT(onUAVField_indexChanged(QString))); + 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); - options_page->SoundCollectionList->clear(); - options_page->SoundCollectionList->addItems(listDirCollections); + _listDirCollections = dirPath.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); + _optionsPage->SoundCollectionList->clear(); + _optionsPage->SoundCollectionList->addItems(_listDirCollections); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::on_soundLanguage_indexChanged(int index) { - options_page->SoundCollectionList->setCurrentIndex(index); + _optionsPage->SoundCollectionList->setCurrentIndex(index); + _currentCollectionPath = _optionsPage->SoundDirectoryPathChooser->path() + + QDir::toNativeSeparators("/" + _optionsPage->SoundCollectionList->currentText()); - currentCollectionPath = options_page->SoundDirectoryPathChooser->path() - + QDir::toNativeSeparators("/" + options_page->SoundCollectionList->currentText()); - - QDir dirPath(currentCollectionPath); + QDir dirPath(_currentCollectionPath); QStringList filters; filters << "*.mp3" << "*.wav"; dirPath.setNameFilters(filters); - listSoundFiles = dirPath.entryList(filters); - listSoundFiles.replaceInStrings(QRegExp(".mp3|.wav"), ""); - options_page->Sound1->clear(); - options_page->Sound2->clear(); - options_page->Sound3->clear(); - options_page->Sound1->addItems(listSoundFiles); - options_page->Sound2->addItem(""); - options_page->Sound2->addItems(listSoundFiles); - options_page->Sound3->addItem(""); - options_page->Sound3->addItems(listSoundFiles); - + _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::changeButtonText(Phonon::State newstate, Phonon::State oldstate) +void NotifyPluginOptionsPage::on_changeButtonText(Phonon::State newstate, Phonon::State oldstate) { //Q_ASSERT(Phonon::ErrorState != newstate); if (newstate == Phonon::PausedState || newstate == Phonon::StoppedState) { - options_page->buttonPlayNotification->setText("Play"); - options_page->buttonPlayNotification->setIcon(QPixmap(":/notify/images/play.png")); + _optionsPage->buttonPlayNotification->setText("Play"); + _optionsPage->buttonPlayNotification->setIcon(QPixmap(":/notify/images/play.png")); } else { if (newstate == Phonon::PlayingState) { - options_page->buttonPlayNotification->setText("Stop"); - options_page->buttonPlayNotification->setIcon(QPixmap(":/notify/images/stop.png")); + _optionsPage->buttonPlayNotification->setText("Stop"); + _optionsPage->buttonPlayNotification->setIcon(QPixmap(":/notify/images/stop.png")); } } } -//----------------------------------------------------------------------------- -void NotifyPluginOptionsPage::onFinishedPlaying() +void NotifyPluginOptionsPage::on_FinishedPlaying() { - notifySound->clear(); + _notifySound->clear(); } -//----------------------------------------------------------------------------- -void NotifyPluginOptionsPage::on_buttonTestSoundNotification_clicked() +void NotifyPluginOptionsPage::on_button_TestSoundNotification_clicked() { NotificationItem* notification = NULL; - - if (-1 == _notifyRulesSelection->currentIndex().row()) - return; - notifySound->clearQueue(); - notification = privListNotifications.at(_notifyRulesSelection->currentIndex().row()); - notification->parseNotifyMessage(); - QStringList sequence = notification->getMessageSequence(); - Q_ASSERT(!!sequence.size()); 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->enqueue(Phonon::MediaSource(item)); } - notifySound->play(); + _notifySound->play(); } -void NotifyPluginOptionsPage::on_chkEnableSound_toggled(bool state) +void NotifyPluginOptionsPage::on_checkEnableSound_toggled(bool state) { bool state1 = 1^state; - QList listOutputs = notifySound->outputPaths(); + QList listOutputs = _notifySound->outputPaths(); Phonon::AudioOutput * audioOutput = (Phonon::AudioOutput*)listOutputs.last().sink(); audioOutput->setMuted(state1); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::updateConfigView(NotificationItem* notification) { Q_ASSERT(notification); - disconnect(options_page->UAVObject, SIGNAL(currentIndexChanged(QString)), + disconnect(_optionsPage->UAVObject, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVObject_indexChanged(QString))); - disconnect(options_page->UAVObjectField, SIGNAL(currentIndexChanged(QString)), - this, SLOT(onUAVField_indexChanged(QString))); + disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), + this, SLOT(on_UAVField_indexChanged(QString))); QString path = notification->getSoundCollectionPath(); - if (path == "") { - //QDir dir = QDir::currentPath(); - //path = QDir::currentPath().left(QDir::currentPath().indexOf("OpenPilot",0,Qt::CaseSensitive))+"../share/sounds"; + if (path.isEmpty()) { path = Utils::PathUtils().InsertDataPath("%%DATAPATH%%sounds"); } - options_page->SoundDirectoryPathChooser->setPath(path); + _optionsPage->SoundDirectoryPathChooser->setPath(path); - if (-1 != options_page->SoundCollectionList->findText(notification->getCurrentLanguage())){ - options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText(notification->getCurrentLanguage())); + if (-1 != _optionsPage->SoundCollectionList->findText(notification->getCurrentLanguage())) { + _optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText(notification->getCurrentLanguage())); } else { - options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText("default")); + _optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default")); } - // Fills the combo boxes for the UAVObjects - QList< QList > objList = objManager.getDataObjects(); + QList< QList > objList = _objManager.getDataObjects(); foreach (QList list, objList) { foreach (UAVDataObject* obj, list) { - options_page->UAVObject->addItem(obj->getName()); + _optionsPage->UAVObject->addItem(obj->getName()); } } - if (options_page->UAVObject->findText(notification->getDataObject())!=-1){ - options_page->UAVObject->setCurrentIndex(options_page->UAVObject->findText(notification->getDataObject())); + if (-1 != _optionsPage->UAVObject->findText(notification->getDataObject())) { + _optionsPage->UAVObject->setCurrentIndex(_optionsPage->UAVObject->findText(notification->getDataObject())); } - options_page->UAVObjectField->clear(); + _optionsPage->UAVObjectField->clear(); QString uavDataObject = notification->getDataObject(); - UAVDataObject* obj = dynamic_cast(objManager.getObject(uavDataObject)); + UAVDataObject* obj = dynamic_cast(_objManager.getObject(uavDataObject)); if (obj != NULL ) { QList fieldList = obj->getFields(); foreach (UAVObjectField* field, fieldList) { - options_page->UAVObjectField->addItem(field->getName()); + _optionsPage->UAVObjectField->addItem(field->getName()); } } - if (-1 != options_page->UAVObjectField->findText(notification->getObjectField())) { - options_page->UAVObjectField->setCurrentIndex(options_page->UAVObjectField->findText(notification->getObjectField())); + if (-1 != _optionsPage->UAVObjectField->findText(notification->getObjectField())) { + _optionsPage->UAVObjectField->setCurrentIndex(_optionsPage->UAVObjectField->findText(notification->getObjectField())); } - if (-1 != options_page->Sound1->findText(notification->getSound1())) { - options_page->Sound1->setCurrentIndex(options_page->Sound1->findText(notification->getSound1())); + if (-1 != _optionsPage->Sound1->findText(notification->getSound1())) { + _optionsPage->Sound1->setCurrentIndex(_optionsPage->Sound1->findText(notification->getSound1())); } else { // show item from default location - options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText("default")); - options_page->Sound1->setCurrentIndex(options_page->Sound1->findText(notification->getSound1())); + _optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default")); + _optionsPage->Sound1->setCurrentIndex(_optionsPage->Sound1->findText(notification->getSound1())); } - if (-1 != options_page->Sound2->findText(notification->getSound2())) { - options_page->Sound2->setCurrentIndex(options_page->Sound2->findText(notification->getSound2())); + if (-1 != _optionsPage->Sound2->findText(notification->getSound2())) { + _optionsPage->Sound2->setCurrentIndex(_optionsPage->Sound2->findText(notification->getSound2())); } else { // show item from default location - options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText("default")); - options_page->Sound2->setCurrentIndex(options_page->Sound2->findText(notification->getSound2())); + _optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default")); + _optionsPage->Sound2->setCurrentIndex(_optionsPage->Sound2->findText(notification->getSound2())); } - if (-1 != options_page->Sound3->findText(notification->getSound3())) { - options_page->Sound3->setCurrentIndex(options_page->Sound3->findText(notification->getSound3())); + if (-1 != _optionsPage->Sound3->findText(notification->getSound3())) { + _optionsPage->Sound3->setCurrentIndex(_optionsPage->Sound3->findText(notification->getSound3())); } else { // show item from default location - options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText("default")); - options_page->Sound3->setCurrentIndex(options_page->Sound3->findText(notification->getSound3())); + _optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default")); + _optionsPage->Sound3->setCurrentIndex(_optionsPage->Sound3->findText(notification->getSound3())); } if (-1 != _valueRange->findText(notification->range())) { @@ -534,120 +508,123 @@ void NotifyPluginOptionsPage::updateConfigView(NotificationItem* notification) setDynamicValueField(notification); - connect(options_page->UAVObject, SIGNAL(currentIndexChanged(QString)), + connect(_optionsPage->UAVObject, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVObject_indexChanged(QString))); - connect(options_page->UAVObjectField, SIGNAL(currentIndexChanged(QString)), - this, SLOT(onUAVField_indexChanged(QString))); + connect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)), + this, SLOT(on_UAVField_indexChanged(QString))); } -//----------------------------------------------------------------------------- void NotifyPluginOptionsPage::setDynamicValueField(NotificationItem* notification) { - if(QSpinBox* spinValue = dynamic_cast(_fieldValue)) + if (QSpinBox* spinValue = dynamic_cast(_fieldValue)) spinValue->setValue(notification->singleValue()); else { - if(QComboBox* comboBoxValue = dynamic_cast(_fieldValue)) + if (QComboBox* comboBoxValue = dynamic_cast(_fieldValue)) comboBoxValue->setCurrentIndex(notification->singleValue()); else { - if(QLineEdit* rangeValue = dynamic_cast(_fieldValue)) { - resetValueRange(); - rangeValue->setText(QString("%1%2").arg(notification->singleValue()) - .arg(notification->valueRange2())); + if (QLineEdit* rangeValue = dynamic_cast(_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; } - } } } -//----------------------------------------------------------------------------- -void NotifyPluginOptionsPage::on_tableNotification_changeSelection( const QItemSelection & selected, const QItemSelection & deselected ) +UAVObjectField* NotifyPluginOptionsPage::getObjectFieldFromPage() { - bool select = false; - notifySound->stop(); - if (selected.indexes().size()) { - select = true; - _selectedNotification = privListNotifications.at(selected.indexes().at(0).row()); - updateConfigView(_selectedNotification); - UAVDataObject* obj = dynamic_cast( objManager.getObject(options_page->UAVObject->currentText())); - UAVObjectField* field = obj->getField(options_page->UAVObjectField->currentText()); - addDynamicField(field); - setDynamicValueField(_selectedNotification); - } - - options_page->buttonModify->setEnabled(select); - options_page->buttonDelete->setEnabled(select); - options_page->buttonPlayNotification->setEnabled(select); + UAVDataObject* obj = dynamic_cast( _objManager.getObject(_optionsPage->UAVObject->currentText())); + return obj->getField(_optionsPage->UAVObjectField->currentText()); } -//----------------------------------------------------------------------------- -void NotifyPluginOptionsPage::on_buttonAddNotification_clicked() + +UAVObjectField* NotifyPluginOptionsPage::getObjectFieldFromSelected() +{ + UAVDataObject* obj = dynamic_cast(_objManager.getObject(_selectedNotification->getDataObject())); + return obj->getField(_selectedNotification->getObjectField()); +} + +void NotifyPluginOptionsPage::on_table_changeSelection( const QItemSelection & selected, const QItemSelection & deselected ) +{ + bool select = false; + _notifySound->stop(); + if (selected.indexes().size()) { + select = true; + _selectedNotification = _privListNotifications.at(selected.indexes().at(0).row()); + UAVObjectField* field = getObjectFieldFromSelected(); + addDynamicField(field); + updateConfigView(_selectedNotification); + } + + _optionsPage->buttonModify->setEnabled(select); + _optionsPage->buttonDelete->setEnabled(select); + _optionsPage->buttonPlayNotification->setEnabled(select); +} + +void NotifyPluginOptionsPage::on_button_AddNotification_clicked() { NotificationItem* notification = new NotificationItem; - if (options_page->SoundDirectoryPathChooser->path()=="") { - QPalette textPalette=options_page->SoundDirectoryPathChooser->palette(); - textPalette.setColor(QPalette::Normal,QPalette::Text, Qt::red); - options_page->SoundDirectoryPathChooser->setPalette(textPalette); - options_page->SoundDirectoryPathChooser->setPath("please select sound collection folder"); - return; + if (_optionsPage->SoundDirectoryPathChooser->path().isEmpty()) { + QPalette textPalette=_optionsPage->SoundDirectoryPathChooser->palette(); + textPalette.setColor(QPalette::Normal,QPalette::Text, Qt::red); + _optionsPage->SoundDirectoryPathChooser->setPalette(textPalette); + _optionsPage->SoundDirectoryPathChooser->setPath("please select sound collection folder"); + return; } - notification->setSoundCollectionPath(options_page->SoundDirectoryPathChooser->path()); - notification->setCurrentLanguage(options_page->SoundCollectionList->currentText()); - notification->setDataObject(options_page->UAVObject->currentText()); - notification->setObjectField(options_page->UAVObjectField->currentText()); + 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(_fieldValue)) + if (QSpinBox* spinValue = dynamic_cast(_fieldValue)) notification->setSingleValue(spinValue->value()); - if (options_page->Sound1->currentText().size() > 0) - notification->setSound1(options_page->Sound1->currentText()); + if (_optionsPage->Sound1->currentText().size() > 0) + notification->setSound1(_optionsPage->Sound1->currentText()); - notification->setSound2(options_page->Sound2->currentText()); - notification->setSound3(options_page->Sound3->currentText()); + notification->setSound2(_optionsPage->Sound2->currentText()); + notification->setSound3(_optionsPage->Sound3->currentText()); - if ( ((!options_page->Sound2->currentText().size()) && (_sayOrder->currentText()=="After second")) - || ((!options_page->Sound3->currentText().size()) && (_sayOrder->currentText()=="After third")) ) { + if ( ((!_optionsPage->Sound2->currentText().size()) && (_sayOrder->currentText()=="After second")) + || ((!_optionsPage->Sound3->currentText().size()) && (_sayOrder->currentText()=="After third")) ) { return; } else { notification->setSayOrder(_sayOrder->currentText()); } _notifyRulesModel->entryAdded(notification); - _notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(privListNotifications.size()-1,0,QModelIndex()), + _notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(_privListNotifications.size()-1,0,QModelIndex()), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); } -//----------------------------------------------------------------------------- -void NotifyPluginOptionsPage::on_buttonDeleteNotification_clicked() +void NotifyPluginOptionsPage::on_button_DeleteNotification_clicked() { _notifyRulesModel->removeRow(_notifyRulesSelection->currentIndex().row()); if (!_notifyRulesModel->rowCount() && (_notifyRulesSelection->currentIndex().row() > 0 && _notifyRulesSelection->currentIndex().row() < _notifyRulesModel->rowCount()) ) { - options_page->buttonDelete->setEnabled(false); - options_page->buttonModify->setEnabled(false); - options_page->buttonPlayNotification->setEnabled(false); + _optionsPage->buttonDelete->setEnabled(false); + _optionsPage->buttonModify->setEnabled(false); + _optionsPage->buttonPlayNotification->setEnabled(false); } - } -//----------------------------------------------------------------------------- -void NotifyPluginOptionsPage::on_buttonModifyNotification_clicked() +void NotifyPluginOptionsPage::on_button_ModifyNotification_clicked() { NotificationItem* notification = new NotificationItem; getOptionsPageValues(notification); - notification->setRetryString(privListNotifications.at(_notifyRulesSelection->currentIndex().row())->retryString()); - notification->setLifetime(privListNotifications.at(_notifyRulesSelection->currentIndex().row())->lifetime()); - notification->setMute(privListNotifications.at(_notifyRulesSelection->currentIndex().row())->mute()); + notification->setRetryString(_privListNotifications.at(_notifyRulesSelection->currentIndex().row())->retryString()); + notification->setLifetime(_privListNotifications.at(_notifyRulesSelection->currentIndex().row())->lifetime()); + notification->setMute(_privListNotifications.at(_notifyRulesSelection->currentIndex().row())->mute()); - privListNotifications.replace(_notifyRulesSelection->currentIndex().row(),notification); + _privListNotifications.replace(_notifyRulesSelection->currentIndex().row(),notification); entryUpdated(_notifyRulesSelection->currentIndex().row()); - } - diff --git a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h index f4a29ae41..3f36f3f4d 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h +++ b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h @@ -57,78 +57,130 @@ using namespace Core; class NotifyPluginOptionsPage : public IOptionsPage { - Q_OBJECT + Q_OBJECT + public: - explicit NotifyPluginOptionsPage(/*NotificationItem *config, */QObject *parent = 0); - ~NotifyPluginOptionsPage(); - QString id() const { return QLatin1String("settings"); } - QString trName() const { return tr("settings"); } - QString category() const { return QLatin1String("Notify Plugin");} - QString trCategory() const { return tr("Notify Plugin");} + + explicit NotifyPluginOptionsPage(QObject *parent = 0); + ~NotifyPluginOptionsPage(); + QString id() const { return QLatin1String("settings"); } + QString trName() const { return tr("settings"); } + QString category() const { return QLatin1String("Notify Plugin");} + QString trCategory() const { return tr("Notify Plugin");} QWidget *createPage(QWidget *parent); void apply(); - void finish(); - void restoreFromSettings(); + void finish(); + void restoreFromSettings(); - void updateConfigView(NotificationItem* notification); - void getOptionsPageValues(NotificationItem* notification); + void updateConfigView(NotificationItem* notification); + void getOptionsPageValues(NotificationItem* notification); + UAVObjectField* getObjectFieldFromPage(); + UAVObjectField* getObjectFieldFromSelected(); signals: void updateNotifications(QList list); - //void resetNotification(void); 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(); + + /** + * 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_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); + + /** + * Important when we change to or from "In range" value + * For enums UI layout stayed the same, but for numeric values + * we need to change UI to show edit line, + * to have possibility assign range limits for value. + */ + void on_rangeValue_indexChanged(QString); + + void on_FinishedPlaying(void); + + 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(); -private slots: - void on_buttonTestSoundNotification_clicked(); - - void on_buttonAddNotification_clicked(); - void on_buttonDeleteNotification_clicked(); - void on_buttonModifyNotification_clicked(); - void on_tableNotification_changeSelection( 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 onUAVField_indexChanged(QString val); - void changeButtonText(Phonon::State newstate, Phonon::State oldstate); - void on_chkEnableSound_toggled(bool state); - void on_rangeValue_indexChanged(QString); - - void onFinishedPlaying(void); - private: - UAVObjectManager& objManager; - SoundNotifyPlugin* owner; - QStringList listDirCollections; - QStringList listSoundFiles; - QString currentCollectionPath; - Phonon::MediaObject *sound1; - Phonon::MediaObject *sound2; - QScopedPointer notifySound; - Phonon::AudioOutput *audioOutput; - QScopedPointer _notifyRulesModel; - QItemSelectionModel* _notifyRulesSelection; - QList privListNotifications; + UAVObjectManager& _objManager; + SoundNotifyPlugin* _owner; + QStringList _listDirCollections; + QStringList _listSoundFiles; + QString _currentCollectionPath; + Phonon::MediaObject* _sound1; + Phonon::MediaObject* _sound2; + QScopedPointer _notifySound; + Phonon::AudioOutput* _audioOutput; - QScopedPointer options_page; + QScopedPointer _notifyRulesModel; + QItemSelectionModel* _notifyRulesSelection; + /** + * Local copy of notification list, which owned by notify plugin. + * Notification list readed once on application loaded, during + * notify plugin startup, then on open options page. + * This copy is simple assignment, but due to implicitly sharing + * we don't have additional cost for that, copy will created + * only after modification of private notify list. + */ + QList _privListNotifications; + + QScopedPointer _optionsPage; + + //! widget to convinient selection of condition for field value (equal, lower, greater) QComboBox* _valueRange; + + //! widget to convinient selection of order in which sounds will be played 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, + //! 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; }; diff --git a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.ui b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.ui index 23d05c2a0..94560ff1a 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.ui +++ b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.ui @@ -266,7 +266,7 @@ p, li { white-space: pre-wrap; } - QAbstractItemView::SingleSelection + QAbstractItemView::ContiguousSelection QAbstractItemView::SelectRows diff --git a/ground/openpilotgcs/src/plugins/notify/notifytablemodel.cpp b/ground/openpilotgcs/src/plugins/notify/notifytablemodel.cpp index 138af106b..b1fd1c737 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifytablemodel.cpp +++ b/ground/openpilotgcs/src/plugins/notify/notifytablemodel.cpp @@ -30,8 +30,6 @@ #include #include -static int _dragStartRow = -1; -static int _dragNumRows = -1; const char* mime_type_notify_table = "openpilot/notify_plugin_table"; NotifyTableModel::NotifyTableModel(QList& parentList, QObject* parent) @@ -47,19 +45,19 @@ bool NotifyTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && role == Qt::DisplayRole) { - if(eMESSAGE_NAME == index.column()) { + if(eMessageName == index.column()) { emit dataChanged(index, index); return true; } } if (index.isValid() && role == Qt::EditRole) { - if(eREPEAT_VALUE == index.column()) + if(eRepeatValue == index.column()) _list.at(index.row())->setRetryString(value.toString()); else { - if(eEXPIRE_TIME == index.column()) + if(eExpireTimer == index.column()) _list.at(index.row())->setLifetime(value.toInt()); else { - if(eENABLE_NOTIFICATION == index.column()) + if(eTurnOn == index.column()) _list.at(index.row())->setMute(value.toBool()); } } @@ -83,16 +81,16 @@ QVariant NotifyTableModel::data(const QModelIndex &index, int role) const { switch(index.column()) { - case eMESSAGE_NAME: - return _list.at(index.row())->parseNotifyMessage(); + case eMessageName: + return _list.at(index.row())->toString(); - case eREPEAT_VALUE: + case eRepeatValue: return _list.at(index.row())->retryString(); - case eEXPIRE_TIME: + case eExpireTimer: return _list.at(index.row())->lifetime(); - case eENABLE_NOTIFICATION: + case eTurnOn: return _list.at(index.row())->mute(); default: @@ -126,13 +124,13 @@ bool NotifyTableModel::insertRows(int position, int rows, const QModelIndex& ind { Q_UNUSED(index); - if((-1 == position) || (-1 == rows) ) + if (-1 == position || -1 == rows) return false; beginInsertRows(QModelIndex(), position, position + rows - 1); - for (int row = 0; row < rows; ++row) { - _list.insert(position, new NotificationItem()); + for (int i = 0; i < rows; ++i) { + _list.insert(position + i, new NotificationItem()); } endInsertRows(); @@ -171,6 +169,17 @@ void NotifyTableModel::entryAdded(NotificationItem* item) entryUpdated(rowCount() - 1); } +Qt::DropActions NotifyTableModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + +QStringList NotifyTableModel::mimeTypes() const +{ + QStringList types; + types << mime_type_notify_table; + return types; +} bool NotifyTableModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex& parent) @@ -198,48 +207,31 @@ bool NotifyTableModel::dropMimeData( const QMimeData * data, Qt::DropAction acti QByteArray encodedData = data->data(mime_type_notify_table); QDataStream stream(&encodedData, QIODevice::ReadOnly); int rows = beginRow; + // read next item from input MIME and drop into the table line by line while(!stream.atEnd()) { qint32 ptr; stream >> ptr; NotificationItem* item = reinterpret_cast(ptr); int dragged = _list.indexOf(item); + // we can drag item from top rows to bottom (DOWN_DIRECTION), + // 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) { qNotifyDebug() << "no such item"; + return false; } - removeRows(rows, 1, QModelIndex()); - insertRows(rows, 1, QModelIndex()); - _list.replace(dragged, item); - // _list.swap(dragged, rows); - ++rows; + _list.replace(rows + direction, item); + Q_ASSERT(removeRows(dragged, 1, QModelIndex())); + if(direction == UP_DIRECTION) + ++rows; }; QModelIndex idxTopLeft = index(beginRow, 0, QModelIndex()); QModelIndex idxBotRight = index(beginRow, columnCount(QModelIndex()), QModelIndex()); emit dataChanged(idxTopLeft, idxBotRight); - //QStringList newItems; - - //removeRows(_dragStartRow, _dragNumRows, QModelIndex()); - //insertRows(beginRow, rows, QModelIndex()); -// int rows = beginRow; -// while (!stream.atEnd()) { -// _list.at(index.row())->deserialize(stream); -// ++rows; -// } - -// while(rows) { -// int column = 0; -// foreach (const QString& text, newItems) { -// QModelIndex idx = index(beginRow, column, QModelIndex()); -// if(!column) -// setData(const_cast(idx), text, Qt::DisplayRole); -// else -// setData(const_cast(idx), text, Qt::EditRole); -// ++column; -// } -// ++beginRow; -// --rows; -// } return true; } @@ -251,35 +243,13 @@ QMimeData* NotifyTableModel::mimeData(const QModelIndexList& indexes) const QDataStream stream(&encodedData, QIODevice::WriteOnly); int rows = 0; foreach (const QModelIndex& index, indexes) { - if(!index.column()) { + if (!index.column()) { qint32 item = reinterpret_cast(_list.at(index.row())); stream << item; + ++rows; } - ++rows; } - -// int numRows = 0; -// foreach (const QModelIndex& index, indexes) { -// if (index.isValid() && index.column()) { -// _list.at(index.row())->serialize(stream); -//// if(!index.column()) { -//// numRows++; -//// QString name = data(index, Qt::DisplayRole).toString(); -//// stream << name; -//// } else { -//// QString text = data(index, Qt::EditRole).toString(); -//// stream << text; -//// } -// } -// } - mimeData->setData(mime_type_notify_table, encodedData); - - //emit dragRows(indexes.at(0).row(), rows); - dropRows(indexes.at(0).row(), rows); - //_dragStartRow = indexes.at(0).row(); - //_dragNumRows = 1/*numRows*/; - return mimeData; } diff --git a/ground/openpilotgcs/src/plugins/notify/notifytablemodel.h b/ground/openpilotgcs/src/plugins/notify/notifytablemodel.h index 3168a848f..28eb8cc68 100644 --- a/ground/openpilotgcs/src/plugins/notify/notifytablemodel.h +++ b/ground/openpilotgcs/src/plugins/notify/notifytablemodel.h @@ -33,72 +33,58 @@ #include #include "notificationitem.h" -enum ColumnNames { eMESSAGE_NAME, eREPEAT_VALUE, eEXPIRE_TIME, eENABLE_NOTIFICATION }; +enum ColumnNames { eMessageName, eRepeatValue, eExpireTimer, eTurnOn }; class NotifyTableModel : public QAbstractTableModel { - Q_OBJECT + Q_OBJECT - enum {eColumnCount = 4 }; + enum {eColumnCount = 4 }; public: - NotifyTableModel(QList& parentList, QObject* parent = 0); - - int rowCount(const QModelIndex& parent = QModelIndex()) const - { - return _list.count(); - } - - int columnCount(const QModelIndex &/*parent*/) const - { - return eColumnCount; - } - - Qt::ItemFlags flags(const QModelIndex &index) const - { - if (!index.isValid()) - return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; - - return QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; - } - - Qt::DropActions supportedDropActions() const + NotifyTableModel(QList& parentList, QObject* parent = 0); + int rowCount(const QModelIndex& parent = QModelIndex()) const { - return Qt::MoveAction; + return _list.count(); } - QStringList mimeTypes() const - { - QStringList types; - types << "application/vnd.text.list"; - return types; - } + int columnCount(const QModelIndex &/*parent*/) const + { + return eColumnCount; + } - bool dropMimeData( const QMimeData * data, Qt::DropAction action, int row, - int column, const QModelIndex& parent); - QMimeData* mimeData(const QModelIndexList &indexes) const; + Qt::ItemFlags flags(const QModelIndex &index) const + { + if (!index.isValid()) + return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; + + return QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + } + QStringList mimeTypes() const; + Qt::DropActions supportedDropActions() const; + bool dropMimeData( const QMimeData * data, Qt::DropAction action, int row, + int column, const QModelIndex& parent); + QMimeData* mimeData(const QModelIndexList &indexes) const; - bool setData(const QModelIndex &index, const QVariant &value, int role); - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - bool insertRows(int position, int rows, const QModelIndex &index); - bool removeRows(int position, int rows, const QModelIndex &index); - - void entryAdded(NotificationItem* item); + bool setData(const QModelIndex &index, const QVariant &value, int role); + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + bool insertRows(int position, int rows, const QModelIndex &index); + bool removeRows(int position, int rows, const QModelIndex &index); + void entryAdded(NotificationItem* item); signals: - void dragRows(int position, int count); + void dragRows(int position, int count); private slots: - void entryUpdated(int offset); - void dropRows(int position, int count) const; + void entryUpdated(int offset); + void dropRows(int position, int count) const; private: - mutable QList& _list; - QStringList _headerStrings; + mutable QList& _list; + QStringList _headerStrings; }; - #endif // NOTIFYTABLEMODEL_H