1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Merge branch 'notify-plugin-merged' into next

Conflicts:
	ground/openpilotgcs/share/openpilotgcs/sounds/default/minus.wav
This commit is contained in:
zedamota 2012-01-09 14:02:04 +00:00
commit 553dab50fb
17 changed files with 3032 additions and 1953 deletions

View File

@ -0,0 +1,217 @@
/**
******************************************************************************
*
* @file NotificationItem.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Notify Plugin configuration header
* @see The GNU Public License (GPL) Version 3
* @defgroup notifyplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef NOTIFICATION_ITEM_H
#define NOTIFICATION_ITEM_H
#include <coreplugin/iuavgadgetconfiguration.h>
#include "qsettings.h"
#include <qstringlist.h>
#include <QTimer>
using namespace Core;
#define DECLARE_SOUND(number) \
QString getSound##number() const { return _sound##number; } \
void setSound##number(QString text) { _sound##number = text; } \
class UAVDataObject;
class UAVObjectField;
class NotificationItem : public QObject
{
Q_OBJECT
public:
enum { eDefaultTimeout = 15 }; // in sec
enum {never,beforeFirst,beforeSecond,afterSecond};
enum {repeatOncePerUpdate,repeatOnce,repeatInstantly,repeat10seconds,
repeat30seconds,repeat1minute};
explicit NotificationItem(QObject *parent = 0);
void copyTo(NotificationItem*) const;
DECLARE_SOUND(1)
DECLARE_SOUND(2)
DECLARE_SOUND(3)
bool getCurrentUpdatePlayed() const {return _currentUpdatePlayed;}
void setCurrentUpdatePlayed(bool value){_currentUpdatePlayed=value;}
int getCondition() const { return _condition; }
void setCondition(int value) { _condition = value; }
int getSayOrder() const { return _sayOrder; }
void setSayOrder(int text) { _sayOrder = text; }
QVariant singleValue() const { return _singleValue; }
void setSingleValue(QVariant value) { _singleValue = value; }
double valueRange2() const { return _valueRange2; }
void setValueRange2(double value) { _valueRange2 = value; }
QString getDataObject() const { return _dataObject; }
void setDataObject(QString text) { _dataObject = text; }
QString getObjectField() const { return _objectField; }
void setObjectField(QString text) { _objectField = text; }
QString getSoundCollectionPath() const { return _soundCollectionPath; }
void setSoundCollectionPath(QString path) { _soundCollectionPath = path; }
QString getCurrentLanguage() const { return _currentLanguage; }
void setCurrentLanguage(QString text) { _currentLanguage = text; }
QStringList getMessageSequence() const { return _messageSequence; }
void setMessageSequence(QStringList sequence) { _messageSequence = sequence; }
int retryValue() const { return _repeatValue; }
void setRetryValue(int value) { _repeatValue = value; }
int lifetime() const { return _expireTimeout; }
void setLifetime(int value) { _expireTimeout = value; }
bool mute() const { return _mute; }
void setMute(bool value) { _mute = value; }
void saveState(QSettings* settings) const;
void restoreState(QSettings* settings);
UAVDataObject* getUAVObject(void);
UAVObjectField* getUAVObjectField(void);
void serialize(QDataStream& stream);
void deserialize(QDataStream& stream);
/**
* 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 == <sound filename>, if sound file exists
* error - string == [missind]<sound filename>, if sound file doesn't exist
*/
QString getSoundCaption(QString fileName);
QTimer* getTimer() const { return _timer; }
void startTimer(int value);
void restartTimer();
void stopTimer();
void disposeTimer();
QTimer* getExpireTimer() const { return _expireTimer; }
void startExpireTimer();
void stopExpireTimer();
void disposeExpireTimer();
bool isNowPlaying;
bool _isPlayed;
static QStringList sayOrderValues;
static QStringList retryValues;
private:
QString checkSoundExists(QString fileName);
private:
bool _currentUpdatePlayed;
QTimer* _timer;
//! time from putting notification in queue till moment when notification became out-of-date
//! NOTE: each notification has it lifetime, this time setups individually for each notification
//! according to its priority
QTimer* _expireTimer;
//! list of wav files from which notification consists
QStringList _messageSequence;
//! path to folder with sound files
QString _soundCollectionPath;
//! language in what notifications will be spelled
QString _currentLanguage;
//! one UAV object per one notification
QString _dataObject;
//! one field value change can be assigned to one notification
QString _objectField;
//! fire condition for UAV field value (lower, greater, in range)
int _condition;
//! possible sounds(at least one required to play notification)
QString _sound1;
QString _sound2;
QString _sound3;
//! order in what sounds 1-3 will be played
int _sayOrder;
//! 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;
double _valueRange2;
//! how often or what periodicaly notification should be played
int _repeatValue;
//! time after event occured till notification became invalid
//! and will be removed from list
int _expireTimeout;
//! enables/disables playing of current notification
bool _mute;
};
Q_DECLARE_METATYPE(NotificationItem*)
#endif // NotificationItem_H

View File

@ -0,0 +1,433 @@
/**
******************************************************************************
*
* @file NotificationItem.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Notify Plugin configuration
* @see The GNU Public License (GPL) Version 3
* @defgroup notifyplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//Qt headers
#include <QtCore/QDataStream>
#include <QFile>
// GCS headers
#include "extensionsystem/pluginmanager.h"
#include "utils/pathutils.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
// Notify plugin headers
#include "notificationitem.h"
#include "notifylogging.h"
QStringList NotificationItem::sayOrderValues;
QStringList NotificationItem::retryValues;
NotificationItem::NotificationItem(QObject *parent)
: QObject(parent)
, _currentUpdatePlayed(false)
, isNowPlaying(0)
, _isPlayed(false)
, _timer(NULL)
, _expireTimer(NULL)
, _soundCollectionPath("")
, _currentLanguage("default")
, _dataObject("")
, _objectField("")
, _condition(0)
, _sound1("")
, _sound2("")
, _sound3("")
, _sayOrder(never)
, _singleValue(0)
, _valueRange2(0)
, _repeatValue(repeatInstantly)
, _expireTimeout(eDefaultTimeout)
, _mute(false)
{
NotificationItem::sayOrderValues.clear();
NotificationItem::sayOrderValues.insert(never,QString(tr("Never")));
NotificationItem::sayOrderValues.insert(beforeFirst,QString(tr("Before first")));
NotificationItem::sayOrderValues.insert(beforeSecond,QString(tr("Before second")));
NotificationItem::sayOrderValues.insert(afterSecond,QString(tr("After second")));
NotificationItem::retryValues.clear();
NotificationItem::retryValues.insert(repeatOnce,QString(tr("Repeat Once")));
NotificationItem::retryValues.insert(repeatOncePerUpdate,QString(tr("Repeat Once per update")));
NotificationItem::retryValues.insert(repeatInstantly,QString(tr("Repeat Instantly")));
NotificationItem::retryValues.insert(repeat10seconds,QString(tr("Repeat 10 seconds")));
NotificationItem::retryValues.insert(repeat30seconds,QString(tr("Repeat 30 seconds")));
NotificationItem::retryValues.insert(repeat1minute,QString(tr("Repeat 1 minute")));
}
void NotificationItem::copyTo(NotificationItem* that) const
{
that->isNowPlaying = isNowPlaying;
that->_isPlayed = _isPlayed;
that->_soundCollectionPath = _soundCollectionPath;
that->_currentLanguage = _currentLanguage;
that->_soundCollectionPath = _soundCollectionPath;
that->_dataObject = _dataObject;
that->_objectField = _objectField;
that->_condition = _condition;
that->_sound1 = _sound1;
that->_sound2 = _sound2;
that->_sound3 = _sound3;
that->_sayOrder = _sayOrder;
that->_singleValue = _singleValue;
that->_valueRange2 = _valueRange2;
that->_repeatValue = _repeatValue;
that->_expireTimeout = _expireTimeout;
that->_mute = _mute;
}
void NotificationItem::saveState(QSettings* settings) const
{
settings->setValue("SoundCollectionPath", Utils::PathUtils().RemoveDataPath(getSoundCollectionPath()));
settings->setValue(QLatin1String("CurrentLanguage"), getCurrentLanguage());
settings->setValue(QLatin1String("ObjectField"), getObjectField());
settings->setValue(QLatin1String("DataObject"), getDataObject());
settings->setValue(QLatin1String("RangeLimit"), getCondition());
settings->setValue(QLatin1String("Value1"), singleValue());
settings->setValue(QLatin1String("Value2"), valueRange2());
settings->setValue(QLatin1String("Sound1"), getSound1());
settings->setValue(QLatin1String("Sound2"), getSound2());
settings->setValue(QLatin1String("Sound3"), getSound3());
settings->setValue(QLatin1String("SayOrder"), getSayOrder());
settings->setValue(QLatin1String("Repeat"), retryValue());
settings->setValue(QLatin1String("ExpireTimeout"), lifetime());
settings->setValue(QLatin1String("Mute"), mute());
}
void NotificationItem::restoreState(QSettings* settings)
{
//settings = Core::ICore::instance()->settings();
setSoundCollectionPath(Utils::PathUtils().InsertDataPath(settings->value(QLatin1String("SoundCollectionPath"), tr("")).toString()));
setCurrentLanguage(settings->value(QLatin1String("CurrentLanguage"), tr("")).toString());
setDataObject(settings->value(QLatin1String("DataObject"), tr("")).toString());
setObjectField(settings->value(QLatin1String("ObjectField"), tr("")).toString());
setCondition(settings->value(QLatin1String("RangeLimit"), tr("")).toInt());
setSound1(settings->value(QLatin1String("Sound1"), tr("")).toString());
setSound2(settings->value(QLatin1String("Sound2"), tr("")).toString());
setSound3(settings->value(QLatin1String("Sound3"), tr("")).toString());
setSayOrder(settings->value(QLatin1String("SayOrder"), tr("")).toInt());
QVariant value = settings->value(QLatin1String("Value1"), tr(""));
setSingleValue(value);
setValueRange2(settings->value(QLatin1String("Value2"), tr("")).toDouble());
setRetryValue(settings->value(QLatin1String("Repeat"), tr("")).toInt());
setLifetime(settings->value(QLatin1String("ExpireTimeout"), tr("")).toInt());
setMute(settings->value(QLatin1String("Mute"), tr("")).toInt());
}
void NotificationItem::serialize(QDataStream& stream)
{
stream << this->_soundCollectionPath;
stream << this->_currentLanguage;
stream << this->_dataObject;
stream << this->_objectField;
stream << this->_condition;
qNotifyDebug()<<"getOptionsPageValues seriaize"<<_condition;
stream << this->_sound1;
stream << this->_sound2;
stream << this->_sound3;
stream << this->_sayOrder;
stream << this->_singleValue;
stream << this->_valueRange2;
stream << this->_repeatValue;
stream << this->_expireTimeout;
stream << this->_mute;
}
void NotificationItem::deserialize(QDataStream& stream)
{
stream >> this->_soundCollectionPath;
stream >> this->_currentLanguage;
stream >> this->_dataObject;
stream >> this->_objectField;
stream >> this->_condition;
stream >> this->_sound1;
stream >> this->_sound2;
stream >> this->_sound3;
stream >> this->_sayOrder;
stream >> this->_singleValue;
stream >> this->_valueRange2;
stream >> this->_repeatValue;
stream >> this->_expireTimeout;
stream >> this->_mute;
}
void NotificationItem::startTimer(int msec)
{
if (!_timer) {
_timer = new QTimer(this);
_timer->setInterval(msec);
}
if (!_timer->isActive())
_timer->start();
}
void NotificationItem::restartTimer()
{
if (!_timer) {
if (!_timer->isActive())
_timer->start();
}
}
void NotificationItem::stopTimer()
{
if (_timer) {
if (_timer->isActive())
_timer->stop();
}
}
void NotificationItem::disposeTimer()
{
if (_timer) {
_timer->stop();
delete _timer;
_timer = NULL;
}
}
void NotificationItem::startExpireTimer()
{
if (!_expireTimer) {
_expireTimer = new QTimer(this);
}
_expireTimer->start(_expireTimeout * 1000);
}
void NotificationItem::stopExpireTimer()
{
if (_expireTimer) {
if (_expireTimer)
_expireTimer->stop();
}
}
void NotificationItem::disposeExpireTimer()
{
if (_expireTimer) {
_expireTimer->stop();
delete _expireTimer;
_expireTimer = NULL;
}
}
int getValuePosition(QString sayOrder)
{
return NotificationItem::sayOrderValues.indexOf(sayOrder)-1;
}
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;
}
QStringList valueToSoundList(QString value)
{
qNotifyDebug()<<"notificationItem valueToSoundList input param"<<value;
// replace point chr if exists
value = value.replace(',', '.');
QStringList numberParts = value.trimmed().split(".");
QStringList digitWavs;
bool negative=false;
if(numberParts.at(0).toInt()<0)
{
negative=true;
digitWavs.append("minus");
numberParts[0]=QString::number(numberParts.at(0).toInt()*-1);
}
if ( (numberParts.at(0).size() == 1) || (numberParts.at(0).toInt() < 20) ) {
// [1] check, is this number < 20, these numbers played by one wav file
digitWavs.append(numberParts.at(0));
} else {
int i=0;
// [2] store two lowest digits of number
int num = numberParts.at(0).right(2).toInt();
if (num < 20 && num != 0) {
// store eighter number in range [0...10) or in range [10...20)
digitWavs.append(numberParts.at(0).right(1 + num/11));
i=2;
}
// [3] prepend 100 and 1000 digits of number
for (;i<numberParts.at(0).size();i++)
{
int offset=0;
if(negative)
offset=1;
digitWavs.insert(offset,numberParts.at(0).at(numberParts.at(0).size()-i-1));
if(digitWavs.at(offset)==QString("0")) {
digitWavs.removeAt(offset);
continue;
}
if (i==1)
digitWavs.replace(0+offset,digitWavs.at(offset)+'0');
if (i==2)
digitWavs.insert(1+offset,"100");
if (i==3)
digitWavs.insert(1+offset,"1000");
}
}
// check, is there fractional part of number?
if (1 < numberParts.size()) {
digitWavs.append("point");
if (numberParts.at(1).size()==1) {
// this mean -> number < 1
digitWavs.append(numberParts.at(1));
} else {
// append fractional part of number
QString left = numberParts.at(1).left(1);
(left == "0") ? digitWavs.append(left) : digitWavs.append(left + '0');
digitWavs.append(numberParts.at(1).right(1));
}
}
qNotifyDebug()<<"notificationItem valueToSoundList return value"<<digitWavs;
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;
UAVObjectField* field = getUAVObjectField();
QString value = stringFromValue(singleValue(), field);
int pos = getSayOrder()-1;
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
UAVObjectField* field = getUAVObjectField();
QString value = stringFromValue(singleValue(), field);
// generate queue of sound files to play
_messageSequence.clear();
int pos = getSayOrder()-1;
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());
}
UAVDataObject* NotificationItem::getUAVObject() {
return dynamic_cast<UAVDataObject*>((ExtensionSystem::PluginManager::instance()->getObject<UAVObjectManager>())->getObject(getDataObject()));
}

View File

@ -10,15 +10,17 @@ QT += phonon
HEADERS += notifyplugin.h \ HEADERS += notifyplugin.h \
notifypluginoptionspage.h \ notifypluginoptionspage.h \
notifypluginconfiguration.h \
notifyitemdelegate.h \ notifyitemdelegate.h \
notifytablemodel.h notifytablemodel.h \
notificationitem.h \
notifylogging.h
SOURCES += notifyplugin.cpp \ SOURCES += notifyplugin.cpp \
notifypluginoptionspage.cpp \ notifypluginoptionspage.cpp \
notifypluginconfiguration.cpp \
notifyitemdelegate.cpp \ notifyitemdelegate.cpp \
notifytablemodel.cpp notifytablemodel.cpp \
notificationitem.cpp \
notifylogging.cpp
OTHER_FILES += NotifyPlugin.pluginspec OTHER_FILES += NotifyPlugin.pluginspec
@ -27,3 +29,5 @@ FORMS += \
RESOURCES += \ RESOURCES += \
res.qrc res.qrc

View File

@ -25,136 +25,132 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "notifyitemdelegate.h"
#include <QtGui> #include <QtGui>
#include "notifyitemdelegate.h"
#include "notifytablemodel.h"
#include "notifylogging.h"
#include "notificationitem.h"
NotifyItemDelegate::NotifyItemDelegate(QObject* parent)
NotifyItemDelegate::NotifyItemDelegate(QStringList items,QObject *parent) : QItemDelegate(parent)
: QItemDelegate(parent), , _parent(parent)
m_parent(parent),
m_items(items) {
}
QWidget *NotifyItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex &index) const
{
if (index.column() == 1) {
QComboBox* editor = new QComboBox(parent);
editor->clear();
editor->addItems(m_items);
//repeatEditor->setCurrentIndex(0);
//repeatEditor->setItemDelegate(new RepeatCounterDelegate());
//connect(repeatEditor,SIGNAL(activated (const QString& )),this,SLOT(selectRow(const QString& )));
//QTableWidgetItem* item = qobject_cast<QTableWidgetItem *>(parent);
//((QTableWidgetItem*)parent)->setSelected(true);
// connect(editor, SIGNAL(editingFinished()),
// this, SLOT(commitAndCloseEditor()));
return editor;
} else
{
if(index.column() == 2)
{
QSpinBox* editor = new QSpinBox(parent);
connect(editor, SIGNAL(editingFinished()),
this, SLOT(commitAndCloseEditor()));
return editor;
}
}
QLineEdit *editor = new QLineEdit(parent);
// connect(editor, SIGNAL(editingFinished()),
// this, SLOT(commitAndCloseEditor()));
return editor;
}
void NotifyItemDelegate::commitAndCloseEditor()
{
QLineEdit *editor = qobject_cast<QLineEdit *>(sender());
if (editor)
{
emit commitData(editor);
emit closeEditor(editor);
} else {
QComboBox* editor = qobject_cast<QComboBox*>(sender());
if (editor)
{
emit commitData(editor);
emit closeEditor(editor);
} else {
QSpinBox* editor = qobject_cast<QSpinBox*>(sender());
if (editor)
{
emit commitData(editor);
emit closeEditor(editor);
}
}
}
}
void NotifyItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
if (edit) {
edit->setText(index.model()->data(index, Qt::EditRole).toString());
} else {
QComboBox * repeatEditor = qobject_cast<QComboBox *>(editor);
if (repeatEditor)
repeatEditor->setCurrentIndex(repeatEditor->findText(index.model()->data(index, Qt::EditRole).toString()));
else {
QSpinBox * expireEditor = qobject_cast<QSpinBox *>(editor);
if (expireEditor)
expireEditor->setValue(index.model()->data(index, Qt::EditRole).toInt());
}
}
}
void NotifyItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model, const QModelIndex &index) const
{
QLineEdit *edit = qobject_cast<QLineEdit *>(editor);
if (edit) {
model->setData(index, edit->text());
} else {
QComboBox * repeatEditor = qobject_cast<QComboBox *>(editor);
if (repeatEditor) {
model->setData(index, repeatEditor->currentText());
} else {
QSpinBox * expireEditor = qobject_cast<QSpinBox *>(editor);
if (expireEditor) {
//expireEditor->interpretText();
model->setData(index, expireEditor->value(), Qt::EditRole);
}
}
}
}
void NotifyItemDelegate::selectRow(const QString & text)
{ {
//QList<QTableWidgetItem *> list = ((QTableWidget*)(sender()->parent()))->findItems(text,Qt::MatchExactly);
QComboBox* combo = qobject_cast<QComboBox*>(sender());
QTableWidget* table = new QTableWidget;
table = (QTableWidget*)(combo->parent());
qDebug()<<table->columnCount();
qDebug()<<table->rowCount();
qDebug()<<table->currentRow();
//table->setCurrentIndex(1);
//table->findItems(text,Qt::MatchExactly);
//item->model()->index()
//item->setSelected(true);
} }
QSize NotifyItemDelegate::sizeHint ( const QStyleOptionViewItem & option, QWidget *NotifyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& /*none*/,
const QModelIndex & index ) const const QModelIndex& index) const
{ {
QSize s = QItemDelegate::sizeHint(option, index); if (eRepeatValue == index.column()) {
s.setHeight(10); QComboBox* editor = new QComboBox(parent);
editor->clear();
return s; editor->addItems(NotificationItem::retryValues);
return editor;
} else {
if (eExpireTimer == index.column()) {
QSpinBox* editor = new QSpinBox(parent);
connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor()));
return editor;
} else {
if (eTurnOn == index.column()) {
QCheckBox* editor = new QCheckBox(parent);
connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor()));
return editor;
}
}
}
QLineEdit *editor = new QLineEdit(parent);
return editor;
}
void NotifyItemDelegate::commitAndCloseEditor()
{
QLineEdit* editor = qobject_cast<QLineEdit*>(sender());
if (editor) {
emit commitData(editor);
emit closeEditor(editor);
} else {
QComboBox* editor = qobject_cast<QComboBox*>(sender());
if (editor)
{
emit commitData(editor);
emit closeEditor(editor);
} else {
QSpinBox* editor = qobject_cast<QSpinBox*>(sender());
if (editor)
{
emit commitData(editor);
emit closeEditor(editor);
} else {
QCheckBox* editor = qobject_cast<QCheckBox*>(sender());
if (editor)
{
emit commitData(editor);
emit closeEditor(editor);
}
}
}
}
}
void NotifyItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QLineEdit* edit = qobject_cast<QLineEdit*>(editor);
if (edit) {
edit->setText(index.model()->data(index, Qt::EditRole).toString());
} else {
QComboBox* repeatEditor = qobject_cast<QComboBox *>(editor);
if (repeatEditor)
repeatEditor->setCurrentIndex(repeatEditor->findText(index.model()->data(index, Qt::EditRole).toString()));
else {
QSpinBox* expireEditor = qobject_cast<QSpinBox *>(editor);
if (expireEditor)
expireEditor->setValue(index.model()->data(index, Qt::EditRole).toInt());
else {
QCheckBox* enablePlayEditor = qobject_cast<QCheckBox *>(editor);
if (enablePlayEditor)
enablePlayEditor->setChecked(index.model()->data(index, Qt::EditRole).toBool());
}
}
}
}
void NotifyItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QLineEdit *edit = qobject_cast<QLineEdit *>(editor);
if (edit) {
model->setData(index, edit->text());
} else {
QComboBox * repeatEditor = qobject_cast<QComboBox *>(editor);
if (repeatEditor) {
model->setData(index, repeatEditor->currentText());
} else {
QSpinBox * expireEditor = qobject_cast<QSpinBox *>(editor);
if (expireEditor) {
model->setData(index, expireEditor->value(), Qt::EditRole);
} else {
QCheckBox* enablePlayEditor = qobject_cast<QCheckBox*>(editor);
if (enablePlayEditor) {
model->setData(index, enablePlayEditor->isChecked(), Qt::EditRole);
}
}
}
}
}
void NotifyItemDelegate::selectRow(const QString& text)
{
QComboBox* combo = qobject_cast<QComboBox*>(sender());
QTableWidget* table = new QTableWidget;
table = (QTableWidget*)(combo->parent());
qNotifyDebug() << table->columnCount();
qNotifyDebug() << table->rowCount();
qNotifyDebug() << table->currentRow();
}
QSize NotifyItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QSize s = QItemDelegate::sizeHint(option, index);
s.setHeight(10);
return s;
} }

View File

@ -31,46 +31,26 @@
#include <QItemDelegate> #include <QItemDelegate>
#include <QComboBox> #include <QComboBox>
//class RepeatCounterDelegate : public QItemDelegate
//{
// Q_OBJECT
//public:
// RepeatCounterDelegate(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;
//private slots:
// void commitAndCloseEditor();
//};
class NotifyItemDelegate : public QItemDelegate class NotifyItemDelegate : public QItemDelegate
{ {
Q_OBJECT Q_OBJECT
public: public:
NotifyItemDelegate(QStringList items, QObject *parent = 0); NotifyItemDelegate(QObject *parent = 0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
const QModelIndex &index) const; const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const; const QModelIndex &index) const;
// bool editorEvent(QEvent * event, QAbstractItemModel * model, QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
// const QStyleOptionViewItem & option, const QModelIndex & index );
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
private:
QObject* m_parent;
QStringList m_items;
QComboBox* repeatEditor;
private slots: private slots:
void selectRow(const QString & text); void selectRow(const QString & text);
void commitAndCloseEditor(); void commitAndCloseEditor();
private:
QObject* _parent;
}; };
#endif // NOTIFYITEMDELEGATE_H #endif // NOTIFYITEMDELEGATE_H

View File

@ -0,0 +1,43 @@
/**
******************************************************************************
*
* @file notifylogging.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Uses to logging only inside notify plugin,
* can be convinient turned on/off
* @see The GNU Public License (GPL) Version 3
* @defgroup notifyplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "notifylogging.h"
#ifdef DEBUG_NOTIFIES_ENABLE
QDebug qNotifyDebug()
{
return qDebug() << "[NOTIFY_PLG]";
}
#endif
#ifndef DEBUG_NOTIFIES_ENABLE
QNoDebug qNotifyDebug()
{
return QNoDebug();
}
#endif

View File

@ -0,0 +1,46 @@
/**
******************************************************************************
*
* @file notifylogging.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Uses to logging only inside notify plugin,
* can be convinient turned on/off
* @see The GNU Public License (GPL) Version 3
* @defgroup notifyplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef NOTIFYLOGGING_H
#define NOTIFYLOGGING_H
#include "QDebug.h"
#define DEBUG_NOTIFIES_ENABLE
#ifdef DEBUG_NOTIFIES_ENABLE
QDebug qNotifyDebug();
#endif
#ifndef DEBUG_NOTIFIES_ENABLE
QNoDebug qNotifyDebug();
#endif
#define qNotifyDebug_if(test) if(test) qNotifyDebug()
#endif // NOTIFYLOGGING_H

View File

@ -26,8 +26,9 @@
*/ */
#include "notifyplugin.h" #include "notifyplugin.h"
#include "notifypluginconfiguration.h" #include "notificationitem.h"
#include "notifypluginoptionspage.h" #include "notifypluginoptionspage.h"
#include "notifylogging.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <QDebug> #include <QDebug>
#include <QtPlugin> #include <QtPlugin>
@ -37,16 +38,16 @@
#include <iostream> #include <iostream>
#include "qxttimer.h" #include "qxttimer.h"
#include "backendcapabilities.h"
static const QString VERSION = "1.0.0"; static const QString VERSION = "1.0.0";
//#define DEBUG_NOTIFIES //#define DEBUG_NOTIFIES
SoundNotifyPlugin::SoundNotifyPlugin() SoundNotifyPlugin::SoundNotifyPlugin()
{ {
phonon.mo = NULL; phonon.mo = NULL;
configured = false;
// Do nothing
} }
SoundNotifyPlugin::~SoundNotifyPlugin() SoundNotifyPlugin::~SoundNotifyPlugin()
@ -54,7 +55,6 @@ SoundNotifyPlugin::~SoundNotifyPlugin()
Core::ICore::instance()->saveSettings(this); Core::ICore::instance()->saveSettings(this);
if (phonon.mo != NULL) if (phonon.mo != NULL)
delete phonon.mo; delete phonon.mo;
// Do nothing
} }
bool SoundNotifyPlugin::initialize(const QStringList& args, QString *errMsg) bool SoundNotifyPlugin::initialize(const QStringList& args, QString *errMsg)
@ -70,15 +70,12 @@ bool SoundNotifyPlugin::initialize(const QStringList& args, QString *errMsg)
void SoundNotifyPlugin::extensionsInitialized() void SoundNotifyPlugin::extensionsInitialized()
{ {
Core::ICore::instance()->readSettings(this); Core::ICore::instance()->readSettings(this);
if ( !configured ){
readConfig_0_0_0();
}
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
connect(pm, SIGNAL(objectAdded(QObject*)), this, SLOT(onTelemetryManagerAdded(QObject*))); connect(pm, SIGNAL(objectAdded(QObject*)), this, SLOT(onTelemetryManagerAdded(QObject*)));
removedNotifies.clear(); _toRemoveNotifications.clear();
connectNotifications(); connectNotifications();
} }
void SoundNotifyPlugin::saveConfig( QSettings* settings, UAVConfigInfo *configInfo){ void SoundNotifyPlugin::saveConfig( QSettings* settings, UAVConfigInfo *configInfo){
@ -95,22 +92,19 @@ void SoundNotifyPlugin::saveConfig( QSettings* settings, UAVConfigInfo *configIn
settings->endGroup(); settings->endGroup();
settings->beginWriteArray("listNotifies"); settings->beginWriteArray("listNotifies");
for (int i = 0; i < lstNotifications.size(); i++) { for (int i = 0; i < _notificationList.size(); i++) {
settings->setArrayIndex(i); settings->setArrayIndex(i);
lstNotifications.at(i)->saveState(settings); _notificationList.at(i)->saveState(settings);
} }
settings->endArray(); settings->endArray();
settings->setValue(QLatin1String("EnableSound"), enableSound); settings->setValue(QLatin1String("EnableSound"), enableSound);
} }
void SoundNotifyPlugin::readConfig( QSettings* settings, UAVConfigInfo *configInfo){ void SoundNotifyPlugin::readConfig( QSettings* settings, UAVConfigInfo *configInfo)
{
if ( configInfo->version() == UAVConfigVersion() ){ // Just for migration to the new format.
// Just for migration to the new format. //Q_ASSERT(configInfo->version() == UAVConfigVersion());
configured = false;
return;
}
settings->beginReadArray("Current"); settings->beginReadArray("Current");
settings->setArrayIndex(0); settings->setArrayIndex(0);
@ -120,52 +114,20 @@ void SoundNotifyPlugin::readConfig( QSettings* settings, UAVConfigInfo *configIn
// read list of notifications from settings // read list of notifications from settings
int size = settings->beginReadArray("listNotifies"); int size = settings->beginReadArray("listNotifies");
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
settings->setArrayIndex(i); settings->setArrayIndex(i);
NotifyPluginConfiguration* notification = new NotifyPluginConfiguration; NotificationItem* notification = new NotificationItem;
notification->restoreState(settings); notification->restoreState(settings);
lstNotifications.append(notification); _notificationList.append(notification);
} }
settings->endArray(); settings->endArray();
setEnableSound(settings->value(QLatin1String("EnableSound"),0).toBool()); setEnableSound(settings->value(QLatin1String("EnableSound"),0).toBool());
configured = true;
} }
void SoundNotifyPlugin::readConfig_0_0_0(){
settings = Core::ICore::instance()->settings();
settings->beginGroup(QLatin1String("NotifyPlugin"));
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);
NotifyPluginConfiguration* notification = new NotifyPluginConfiguration;
notification->restoreState(settings);
lstNotifications.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) void SoundNotifyPlugin::onTelemetryManagerAdded(QObject* obj)
{ {
telMngr = qobject_cast<TelemetryManager *>(obj); telMngr = qobject_cast<TelemetryManager *>(obj);
if(telMngr) if (telMngr)
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect())); connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
} }
void SoundNotifyPlugin::shutdown() void SoundNotifyPlugin::shutdown()
@ -175,340 +137,400 @@ void SoundNotifyPlugin::shutdown()
void SoundNotifyPlugin::onAutopilotDisconnect() void SoundNotifyPlugin::onAutopilotDisconnect()
{ {
connectNotifications(); connectNotifications();
} }
/*! /*!
clear any notify timers from previous flight; clear any notify timers from previous flight;
reset will be perform on start of option page reset will be perform on start of option page
*/ */
void SoundNotifyPlugin::resetNotification(void) void SoundNotifyPlugin::resetNotification(void)
{ {
//first, reject empty args and unknown fields. //first, reject empty args and unknown fields.
foreach(NotifyPluginConfiguration* notify,lstNotifications) { foreach(NotificationItem* ntf, _notificationList) {
if(notify->timer) ntf->disposeTimer();
{ disconnect(ntf->getTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
disconnect(notify->timer, SIGNAL(timeout()), this, SLOT(repeatTimerHandler())); ntf->disposeExpireTimer();
notify->timer->stop(); disconnect(ntf->getExpireTimer(), SIGNAL(timeout()), this, SLOT(on_timerRepeated_Notification()));
delete notify->timer; }
notify->timer = NULL;
}
if(notify->expireTimer)
{
disconnect(notify->expireTimer, SIGNAL(timeout()), this, SLOT(expireTimerHandler()));
notify->expireTimer->stop();
delete notify->expireTimer;
notify->expireTimer = NULL;
}
}
} }
/*! /*!
update list of notifies; update list of notifies;
will be perform on OK or APPLY press of option page will be perform on OK or APPLY press of option page
*/ */
void SoundNotifyPlugin::updateNotificationList(QList<NotifyPluginConfiguration*> list) void SoundNotifyPlugin::updateNotificationList(QList<NotificationItem*> list)
{ {
removedNotifies.clear(); _toRemoveNotifications.clear();
resetNotification(); resetNotification();
lstNotifications.clear(); _notificationList.clear();
lstNotifications=list; _notificationList=list;
connectNotifications(); connectNotifications();
Core::ICore::instance()->saveSettings(this); Core::ICore::instance()->saveSettings(this);
} }
void SoundNotifyPlugin::connectNotifications() void SoundNotifyPlugin::connectNotifications()
{ {
foreach(UAVDataObject* obj,lstNotifiedUAVObjects) { foreach(UAVDataObject* obj,lstNotifiedUAVObjects) {
if (obj != NULL) 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) { if (phonon.mo != NULL) {
delete phonon.mo; delete phonon.mo;
phonon.mo = NULL; phonon.mo = NULL;
}
if (!enableSound) return;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
lstNotifiedUAVObjects.clear();
_pendingNotifications.clear();
_notificationList.append(_toRemoveNotifications);
_toRemoveNotifications.clear();
//first, reject empty args and unknown fields.
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(on_arrived_Notification(UAVObject*)));
}
} else {
qNotifyDebug() << "Error: Object is unknown (" << notify->getDataObject() << ").";
} }
}
if(!enableSound) return; if (_notificationList.isEmpty()) return;
// set notification message to current event
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); phonon.mo = Phonon::createPlayer(Phonon::NotificationCategory);
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); phonon.mo->clearQueue();
phonon.firstPlay = true;
lstNotifiedUAVObjects.clear(); QList<Phonon::AudioOutputDevice> audioOutputDevices =
pendingNotifications.clear(); Phonon::BackendCapabilities::availableAudioOutputDevices();
lstNotifications.append(removedNotifies); foreach(Phonon::AudioOutputDevice dev, audioOutputDevices) {
removedNotifies.clear(); qNotifyDebug() << "Notify: Audio Output device: " << dev.name() << " - " << dev.description();
}
//first, reject empty args and unknown fields. connect(phonon.mo, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
foreach(NotifyPluginConfiguration* notify,lstNotifications) { this, SLOT(stateChanged(Phonon::State,Phonon::State)));
notify->firstStart=true;
notify->isNowPlaying=false;
// if(notify->timer)
// {
// disconnect(notify->timer, SIGNAL(timeout()), this, SLOT(repeatTimerHandler()));
// notify->timer->stop();
// delete notify->timer;
// notify->timer = NULL;
// }
// if(notify->expireTimer)
// {
// disconnect(notify->expireTimer, SIGNAL(timeout()), this, SLOT(expireTimerHandler()));
// notify->expireTimer->stop();
// delete notify->expireTimer;
// notify->expireTimer = NULL;
// }
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*)));
}
} else
std::cout << "Error: Object is unknown (" << notify->getDataObject().toStdString() << ")." << std::endl;
}
if(lstNotifications.isEmpty()) return;
// set notification message to current event
phonon.mo = Phonon::createPlayer(Phonon::NotificationCategory);
phonon.mo->clearQueue();
phonon.firstPlay = true;
#ifdef DEBUG_NOTIFIES
QList<Phonon::AudioOutputDevice> audioOutputDevices =
Phonon::BackendCapabilities::availableAudioOutputDevices();
foreach(Phonon::AudioOutputDevice dev, audioOutputDevices) {
qDebug() << "Notify: Audio Output device: " << dev.name() << " - " << dev.description();
}
#endif
connect(phonon.mo,SIGNAL(stateChanged(Phonon::State,Phonon::State)),
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, _notificationList) {
if (object->getName() != ntf->getDataObject())
continue;
foreach(NotifyPluginConfiguration* notification, lstNotifications) {
if(object->getName()!=notification->getDataObject())
continue;
if(nowPlayingConfiguration == notification) // skip duplicate notifications
continue; if (_nowPlayingNotification == ntf)
continue;
if(notification->getRepeatFlag()!= "Repeat Instantly" && // skip periodical notifications
notification->getRepeatFlag()!= "Repeat Once" && !notification->firstStart) // this condition accepts:
continue; // 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->retryValue() != NotificationItem::repeatInstantly && ntf->retryValue() != NotificationItem::repeatOncePerUpdate &&
ntf->retryValue() != NotificationItem::repeatOnce && ntf->_isPlayed)
continue;
checkNotificationRule(notification,object); qNotifyDebug() << QString("new notification: | %1 | %2 | val1: %3 | val2: %4")
} .arg(ntf->getDataObject())
connect(object, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(appendNotification(UAVObject*))); .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(on_arrived_Notification(UAVObject*)), Qt::UniqueConnection);
} }
void SoundNotifyPlugin::checkNotificationRule(NotifyPluginConfiguration* notification, UAVObject* object) void SoundNotifyPlugin::on_timerRepeated_Notification()
{ {
bool condition=false; NotificationItem* notification = static_cast<NotificationItem*>(sender()->parent());
double threshold; if (!notification)
QString direction; return;
QString fieldName; // skip duplicate notifications
threshold = notification->getSpinBoxValue(); // WARNING: generally we shoudn't ever trap here
direction = notification->getValue(); // this means, that timer fires to early and notification overlap itself
fieldName = notification->getObjectField(); if (_nowPlayingNotification == notification) {
UAVObjectField* field = object->getField(fieldName); qNotifyDebug() << "WARN: on_timerRepeated - notification was skipped!";
if (field->getName()!="") { notification->restartTimer();
double value = field->getDouble(); return;
}
switch(direction[0].toAscii()) qNotifyDebug() << QString("repeatTimer: %1% | %2 | %3").arg(notification->getDataObject())
{ .arg(notification->getObjectField())
case 'E': .arg(notification->toString());
if(value==threshold)
condition = true;
break;
case 'G':
if(value>threshold)
condition = true;
break;
case 'L':
if(value<threshold)
condition = true;
break;
}
}
if(condition) ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
{ UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
if(!playNotification(notification)) UAVObject* object = objManager->getObject(notification->getDataObject());
{ if (object)
if(!pendingNotifications.contains(notification)) checkNotificationRule(notification,object);
{
if(notification->timer)
if(notification->timer->isActive())
notification->timer->stop();
#ifdef DEBUG_NOTIFIES
qDebug() << "add to pending list - " << notification->parseNotifyMessage();
#endif
// if audio is busy, start expiration timer
//ms = (notification->getExpiredTimeout()[in sec])*1000
//QxtTimer::singleShot(notification->getExpireTimeout()*1000, this, SLOT(expirationTimerHandler(NotifyPluginConfiguration*)), qVariantFromValue(notification));
pendingNotifications.append(notification);
if(!notification->expireTimer)
{
notification->expireTimer = new QTimer(notification);
connect(notification->expireTimer, SIGNAL(timeout()), this, SLOT(expireTimerHandler()));
}
notification->expireTimer->start(notification->getExpireTimeout()*1000);
}
}
}
} }
bool SoundNotifyPlugin::playNotification(NotifyPluginConfiguration* notification)
void SoundNotifyPlugin::on_expiredTimer_Notification()
{ {
// Check: race condition, if phonon.mo got deleted don't go further // fire expire timer
if (phonon.mo == NULL) NotificationItem* notification = static_cast<NotificationItem*>(sender()->parent());
return false; if(!notification)
return;
notification->stopExpireTimer();
#ifdef DEBUG_NOTIFIES volatile QMutexLocker lock(&_mutex);
qDebug() << "Phonon State: " << phonon.mo->state();
#endif
if((phonon.mo->state()==Phonon::PausedState) ||
(phonon.mo->state()==Phonon::StoppedState) ||
phonon.firstPlay)
{
// don't fire expire timer
//notification->expire = false;
nowPlayingConfiguration = notification;
if(notification->expireTimer)
notification->expireTimer->stop();
if(notification->getRepeatFlag()=="Repeat Once") if (!_pendingNotifications.isEmpty()) {
{ qNotifyDebug() << QString("expireTimer: %1% | %2 | %3").arg(notification->getDataObject())
removedNotifies.append(lstNotifications.takeAt(lstNotifications.indexOf(notification))); .arg(notification->getObjectField())
//if(!notification->firstStart) return true; .arg(notification->toString());
}
else {
if(notification->getRepeatFlag()!="Repeat Instantly")
{
QRegExp rxlen("(\\d+)");
QString value;
int timer_value;
int pos = rxlen.indexIn(notification->getRepeatFlag());
if (pos > -1) {
value = rxlen.cap(1); // "189"
timer_value = (value.toInt()+8)*1000; //ms*1000 + average duration of meassage
}
if(!notification->timer) _pendingNotifications.removeOne(notification);
{ }
notification->timer = new QTimer(notification);
notification->timer->setInterval(timer_value);
connect(notification->timer, SIGNAL(timeout()), this, SLOT(repeatTimerHandler()));
}
if(!notification->timer->isActive())
notification->timer->start();
//QxtTimer::singleShot(timer_value, this, SLOT(repeatTimerHandler(NotifyPluginConfiguration*)), qVariantFromValue(notification));
}
}
notification->firstStart=false;
phonon.mo->clear();
QString str = notification->parseNotifyMessage();
#ifdef DEBUG_NOTIFIES
qDebug() << "play notification - " << str;
#endif
foreach(QString item, notification->getNotifyMessageList()) {
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(NotifyPluginConfiguration* notification)
//{
// qDebug() << "repeatTimerHandler - " << notification->parseNotifyMessage();
// ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
// UAVObject* object = objManager->getObject(notification->getDataObject());
// if(object)
// checkNotificationRule(notification,object);
//}
void SoundNotifyPlugin::repeatTimerHandler()
{
NotifyPluginConfiguration* notification = static_cast<NotifyPluginConfiguration*>(sender()->parent());
#ifdef DEBUG_NOTIFIES
qDebug() << "repeatTimerHandler - " << notification->parseNotifyMessage();
#endif
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVObject* object = objManager->getObject(notification->getDataObject());
if(object)
checkNotificationRule(notification,object);
}
void SoundNotifyPlugin::expireTimerHandler()
{
// fire expire timer
NotifyPluginConfiguration* notification = static_cast<NotifyPluginConfiguration*>(sender()->parent());
notification->expireTimer->stop();
if(!pendingNotifications.isEmpty())
{
#ifdef DEBUG_NOTIFIES
qDebug() << "expireTimerHandler - " << notification->parseNotifyMessage();
#endif
pendingNotifications.removeOne(notification);
}
} }
void SoundNotifyPlugin::stateChanged(Phonon::State newstate, Phonon::State oldstate) void SoundNotifyPlugin::stateChanged(Phonon::State newstate, Phonon::State oldstate)
{ {
Q_UNUSED(oldstate) Q_UNUSED(oldstate)
#ifdef DEBUG_NOTIFIES //qNotifyDebug() << "File length (ms): " << phonon.mo->totalTime();
qDebug() << "File length (ms): " << phonon.mo->totalTime();
qDebug() << "New State: " << newstate;
#endif
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
// This is a hack to force Linux to wait until the end of the // This is a hack to force Linux to wait until the end of the
// wav file before moving to the next in the queue. // wav file before moving to the next in the queue.
// I wish I did not have to go through a #define, but I did not // I wish I did not have to go through a #define, but I did not
// manage to make this work on both platforms any other way! // manage to make this work on both platforms any other way!
if (phonon.mo->totalTime()>0) if (phonon.mo->totalTime()>0)
phonon.mo->setTransitionTime(phonon.mo->totalTime()); phonon.mo->setTransitionTime(phonon.mo->totalTime());
#endif #endif
if((newstate == Phonon::PausedState) || if ((newstate == Phonon::PausedState) ||
(newstate == Phonon::StoppedState)) (newstate == Phonon::StoppedState))
{ {
nowPlayingConfiguration=NULL; qNotifyDebug() << "New State: " << QVariant(newstate).toString();
if(!pendingNotifications.isEmpty())
{ volatile QMutexLocker lock(&_mutex);
NotifyPluginConfiguration* notification = pendingNotifications.takeFirst(); // assignment to NULL needed to detect that palying is finished
#ifdef DEBUG_NOTIFIES // it's useful in repeat timer handler, where we can detect
qDebug() << "play audioFree - " << notification->parseNotifyMessage(); // that notification has not overlap with itself
#endif _nowPlayingNotification = NULL;
playNotification(notification);
if (!_pendingNotifications.isEmpty())
{
NotificationItem* notification = _pendingNotifications.takeFirst();
qNotifyDebug_if(notification) << "play audioFree - " << notification->toString();
playNotification(notification);
qNotifyDebug()<<"end playNotification";
}
} else {
if (newstate == Phonon::ErrorState) {
if (phonon.mo->errorType()==0) {
qDebug() << "Phonon::ErrorState: ErrorType = " << phonon.mo->errorType();
phonon.mo->clearQueue();
}
}
}
}
bool checkRange(QString fieldValue, QString enumValue, QStringList values, int direction)
{
bool ret = false;
switch(direction)
{
case NotifyPluginOptionsPage::equal:
ret = !QString::compare(enumValue, fieldValue, Qt::CaseInsensitive) ? true : false;
break;
default:
ret = true;
break;
};
return ret;
}
bool checkRange(double fieldValue, double min, double max, int direction)
{
bool ret = false;
//Q_ASSERT(min < max);
switch(direction)
{
case NotifyPluginOptionsPage::equal:
ret = (fieldValue == min);
break;
case NotifyPluginOptionsPage::bigger:
ret = (fieldValue > min);
break;
case NotifyPluginOptionsPage::smaller:
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;
int direction = notification->getCondition();
QString fieldName = notification->getObjectField();
UAVObjectField* field = object->getField(fieldName);
if (field->getName().isEmpty())
return;
QVariant value = field->getValue();
if(UAVObjectField::ENUM == field->getType()) {
qNotifyDebug()<<"Check range ENUM"<<value.toString()<<"|"<<notification->singleValue().toString()<<"|"<<field->getOptions()<<"|"<<
direction<<checkRange(value.toString(),
notification->singleValue().toString(),
field->getOptions(),
direction);;
condition = checkRange(value.toString(),
notification->singleValue().toString(),
field->getOptions(),
direction);
} else {
qNotifyDebug()<<"Check range VAL"<<value.toString()<<"|"<<notification->singleValue().toString()<<"|"<<field->getOptions()<<"|"<<
direction<<checkRange(value.toDouble(),
notification->singleValue().toDouble(),
notification->valueRange2(),
direction);
condition = checkRange(value.toDouble(),
notification->singleValue().toDouble(),
notification->valueRange2(),
direction);
}
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();
notification->setCurrentUpdatePlayed(false);
return;
}
if(notification->retryValue() == NotificationItem::repeatOncePerUpdate && notification->getCurrentUpdatePlayed())
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->retryValue() == NotificationItem::repeatOnce) {
_toRemoveNotifications.append(_notificationList.takeAt(_notificationList.indexOf(notification)));
}
else if(notification->retryValue() == NotificationItem::repeatOncePerUpdate)
notification->setCurrentUpdatePlayed(true);
else {
if (notification->retryValue() != NotificationItem::repeatInstantly) {
QRegExp rxlen("(\\d+)");
QString value;
int timer_value=0;
int pos = rxlen.indexIn(NotificationItem::retryValues.at(notification->retryValue()));
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;
} }
} else if (newstate == Phonon::ErrorState)
{ notification->startTimer(timer_value);
if(phonon.mo->errorType()==0) { connect(notification->getTimer(), SIGNAL(timeout()),
qDebug() << "Phonon::ErrorState: ErrorType = " << phonon.mo->errorType(); this, SLOT(on_timerRepeated_Notification()), Qt::UniqueConnection);
phonon.mo->clearQueue(); }
} }
} phonon.mo->clear();
// if(newstate == Phonon::BufferingState) qNotifyDebug() << "play: " << notification->toString();
// qDebug() << "Phonon::BufferingState!!!"; foreach (QString item, notification->toSoundList()) {
Phonon::MediaSource *ms = new Phonon::MediaSource(item);
ms->setAutoDelete(true);
phonon.mo->enqueue(*ms);
}
qNotifyDebug()<<"begin play";
phonon.mo->play();
qNotifyDebug()<<"end 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) Q_EXPORT_PLUGIN(SoundNotifyPlugin)

View File

@ -32,7 +32,7 @@
#include "uavtalk/telemetrymanager.h" #include "uavtalk/telemetrymanager.h"
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavobject.h" #include "uavobject.h"
#include "notifypluginconfiguration.h" #include "notificationitem.h"
#include <QSettings> #include <QSettings>
#include <phonon/MediaObject> #include <phonon/MediaObject>
@ -44,71 +44,69 @@ class NotifyPluginOptionsPage;
typedef struct { typedef struct {
Phonon::MediaObject* mo; Phonon::MediaObject* mo;
NotifyPluginConfiguration* notify; NotificationItem* notify;
bool firstPlay; bool firstPlay;
} PhononObject, *pPhononObject; } PhononObject, *pPhononObject;
class SoundNotifyPlugin : public Core::IConfigurablePlugin class SoundNotifyPlugin : public Core::IConfigurablePlugin
{ {
Q_OBJECT Q_OBJECT
public: public:
SoundNotifyPlugin(); SoundNotifyPlugin();
~SoundNotifyPlugin(); ~SoundNotifyPlugin();
void extensionsInitialized(); void extensionsInitialized();
bool initialize(const QStringList & arguments, QString * errorString); bool initialize(const QStringList & arguments, QString * errorString);
void readConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo); void readConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo);
void saveConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo); void saveConfig( QSettings* qSettings, Core::UAVConfigInfo *configInfo);
void shutdown(); void shutdown();
QList<NotifyPluginConfiguration*> getListNotifications() { return lstNotifications; } QList<NotificationItem*> getListNotifications() { return _notificationList; }
//void setListNotifications(QList<NotifyPluginConfiguration*>& list_notify) { } NotificationItem* getCurrentNotification(){ return &currentNotification;}
NotifyPluginConfiguration* getCurrentNotification(){ return &currentNotification;}
bool getEnableSound() const { return enableSound; }
void setEnableSound(bool value) {enableSound = value; }
bool getEnableSound() const { return enableSound; }
void setEnableSound(bool value) {enableSound = value; }
private: private:
bool configured; // just for migration,delete later Q_DISABLE_COPY(SoundNotifyPlugin)
bool enableSound;
QList< QList<Phonon::MediaSource>* > lstMediaSource;
QStringList mediaSource;
//QMap<QString, Phonon::MediaObject*> mapMediaObjects;
QMultiMap<QString, PhononObject> mapMediaObjects;
QSettings* settings; bool playNotification(NotificationItem* notification);
void checkNotificationRule(NotificationItem* notification, UAVObject* object);
QList<UAVDataObject*> lstNotifiedUAVObjects; void readConfig_0_0_0();
QList<NotifyPluginConfiguration*> lstNotifications;
QList<NotifyPluginConfiguration*> pendingNotifications;
QList<NotifyPluginConfiguration*> removedNotifies;
NotifyPluginConfiguration currentNotification;
NotifyPluginConfiguration* nowPlayingConfiguration;
QString m_field;
PhononObject phonon;
NotifyPluginOptionsPage *mop;
TelemetryManager* telMngr;
bool playNotification(NotifyPluginConfiguration* notification);
void checkNotificationRule(NotifyPluginConfiguration* notification, UAVObject* object);
void readConfig_0_0_0();
private slots: private slots:
void onTelemetryManagerAdded(QObject* obj);
void onAutopilotDisconnect(); void onTelemetryManagerAdded(QObject* obj);
void connectNotifications(); void onAutopilotDisconnect();
void updateNotificationList(QList<NotifyPluginConfiguration*> list); void connectNotifications();
void resetNotification(void); void updateNotificationList(QList<NotificationItem*> list);
void appendNotification(UAVObject *object); void resetNotification(void);
void repeatTimerHandler(void); void on_arrived_Notification(UAVObject *object);
void expireTimerHandler(void); void on_timerRepeated_Notification(void);
void stateChanged(Phonon::State newstate, Phonon::State oldstate); void on_expiredTimer_Notification(void);
void stateChanged(Phonon::State newstate, Phonon::State oldstate);
private:
bool enableSound;
QList< QList<Phonon::MediaSource>* > lstMediaSource;
QStringList mediaSource;
QMultiMap<QString, PhononObject> mapMediaObjects;
QSettings* settings;
QList<UAVDataObject*> lstNotifiedUAVObjects;
QList<NotificationItem*> _notificationList;
QList<NotificationItem*> _pendingNotifications;
QList<NotificationItem*> _toRemoveNotifications;
NotificationItem currentNotification;
NotificationItem* _nowPlayingNotification;
PhononObject phonon;
NotifyPluginOptionsPage* mop;
TelemetryManager* telMngr;
QMutex _mutex;
}; };
#endif // SOUNDNOTIFYPLUGIN_H #endif // SOUNDNOTIFYPLUGIN_H

View File

@ -1,245 +0,0 @@
/**
******************************************************************************
*
* @file notifyPluginConfiguration.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Notify Plugin configuration
* @see The GNU Public License (GPL) Version 3
* @defgroup notifyplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "notifypluginconfiguration.h"
#include <QtCore/QDataStream>
#include <QFile>
#include "utils/pathutils.h"
NotifyPluginConfiguration::NotifyPluginConfiguration(QObject *parent) :
QObject(parent),
isNowPlaying(0),
firstStart(1),
soundCollectionPath(""),
currentLanguage("default"),
dataObject(""),
objectField(""),
value("Equal to"),
sound1(""),
sound2(""),
sound3(""),
sayOrder("Never"),
spinBoxValue(0),
repeatString("Repeat Instantly"),
repeatTimeout(true),
expireTimeout(15)
{
timer = NULL;
expireTimer = NULL;
}
void NotifyPluginConfiguration::copyTo(NotifyPluginConfiguration* that) const
{
that->isNowPlaying = isNowPlaying;
that->firstStart = firstStart;
that->soundCollectionPath = soundCollectionPath;
that->currentLanguage = currentLanguage;
that->soundCollectionPath = soundCollectionPath;
that->dataObject = dataObject;
that->objectField = objectField;
that->value = value;
that->sound1 = sound1;
that->sound2 = sound2;
that->sound3 = sound3;
that->sayOrder = sayOrder;
that->spinBoxValue = spinBoxValue;
that->repeatString = repeatString;
that->repeatTimeout = repeatTimeout;
that->expireTimeout = expireTimeout;
}
void NotifyPluginConfiguration::saveState(QSettings* settings) const
{
settings->setValue("SoundCollectionPath", Utils::PathUtils().RemoveDataPath(getSoundCollectionPath()));
settings->setValue(QLatin1String("CurrentLanguage"), getCurrentLanguage());
settings->setValue(QLatin1String("ObjectField"), getObjectField());
settings->setValue(QLatin1String("DataObject"), getDataObject());
settings->setValue(QLatin1String("Value"), getValue());
settings->setValue(QLatin1String("ValueSpinBox"), getSpinBoxValue());
settings->setValue(QLatin1String("Sound1"), getSound1());
settings->setValue(QLatin1String("Sound2"), getSound2());
settings->setValue(QLatin1String("Sound3"), getSound3());
settings->setValue(QLatin1String("SayOrder"), getSayOrder());
settings->setValue(QLatin1String("Repeat"), getRepeatFlag());
settings->setValue(QLatin1String("ExpireTimeout"), getExpireTimeout());
}
void NotifyPluginConfiguration::restoreState(QSettings* settings)
{
//settings = Core::ICore::instance()->settings();
setSoundCollectionPath(Utils::PathUtils().InsertDataPath(settings->value(QLatin1String("SoundCollectionPath"), tr("")).toString()));
setCurrentLanguage(settings->value(QLatin1String("CurrentLanguage"), tr("")).toString());
setDataObject(settings->value(QLatin1String("DataObject"), tr("")).toString());
setObjectField(settings->value(QLatin1String("ObjectField"), tr("")).toString());
setValue(settings->value(QLatin1String("Value"), tr("")).toString());
setSound1(settings->value(QLatin1String("Sound1"), tr("")).toString());
setSound2(settings->value(QLatin1String("Sound2"), tr("")).toString());
setSound3(settings->value(QLatin1String("Sound3"), tr("")).toString());
setSayOrder(settings->value(QLatin1String("SayOrder"), tr("")).toString());
setSpinBoxValue(settings->value(QLatin1String("ValueSpinBox"), tr("")).toDouble());
setRepeatFlag(settings->value(QLatin1String("Repeat"), tr("")).toString());
setExpireTimeout(settings->value(QLatin1String("ExpireTimeout"), tr("")).toInt());
}
QString NotifyPluginConfiguration::parseNotifyMessage()
{
// tips:
// check of *.wav files exist needed for playing phonon queues;
// if phonon player don't find next file in queue, it buzz
QString str,str1;
str1= getSayOrder();
str = QString("%L1 ").arg(getSpinBoxValue());
int position = 0xFF;
// generate queue of sound files to play
notifyMessageList.clear();
if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound1()+".wav")))
notifyMessageList.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound1()+".wav"));
else
if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound1()+".wav")))
notifyMessageList.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound1()+".wav"));
if(getSound2()!="")
{
if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound2()+".wav")))
notifyMessageList.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/" + getCurrentLanguage()+"/"+getSound2()+".wav"));
else
if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound2()+".wav")))
notifyMessageList.append(QDir::toNativeSeparators(getSoundCollectionPath() + "/default/"+getSound2()+".wav"));
}
if(getSound3()!="")
{
if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath()+ "/" + getCurrentLanguage()+"/"+getSound3()+".wav")))
notifyMessageList.append(QDir::toNativeSeparators(getSoundCollectionPath()+ "/" + getCurrentLanguage()+"/"+getSound3()+".wav"));
else
if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+getSound3()+".wav")))
notifyMessageList.append(QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+getSound3()+".wav"));
}
switch(str1.at(0).toAscii())
{
case 'N'://NEVER:
str = getSound1()+" "+getSound2()+" "+getSound3();
position = 0xFF;
break;
case 'B'://BEFORE:
str = QString("%L1 ").arg(getSpinBoxValue())+getSound1()+" "+getSound2()+" "+getSound3();
position = 0;
break;
case 'A'://AFTER:
switch(str1.at(6).toAscii())
{
case 'f':
str = getSound1()+QString(" %L1 ").arg(getSpinBoxValue())+getSound2()+" "+getSound3();
position = 1;
break;
case 's':
str = getSound1()+" "+getSound2()+QString(" %L1").arg(getSpinBoxValue())+" "+getSound3();
position = 2;
break;
case 't':
str = getSound1()+" "+getSound2()+" "+getSound3()+QString(" %L1").arg(getSpinBoxValue());
position = 3;
break;
}
break;
}
if(position!=0xFF)
{
QStringList numberParts = QString("%1").arg(getSpinBoxValue()).trimmed().split(".");
QStringList numberFiles;
if((numberParts.at(0).size()==1) || (numberParts.at(0).toInt()<20))
{
//if(numberParts.at(0)!="0")
numberFiles.append(numberParts.at(0));
} else {
int i=0;
if(numberParts.at(0).right(2).toInt()<20 && numberParts.at(0).right(2).toInt()!=0) {
if(numberParts.at(0).right(2).toInt()<10)
numberFiles.append(numberParts.at(0).right(1));
else
numberFiles.append(numberParts.at(0).right(2));
i=2;
}
for(;i<numberParts.at(0).size();i++)
{
numberFiles.prepend(numberParts.at(0).at(numberParts.at(0).size()-i-1));
if(numberFiles.first()==QString("0")) {
numberFiles.removeFirst();
continue;
}
if(i==1)
numberFiles.replace(0,numberFiles.first()+'0');
if(i==2)
numberFiles.insert(1,"100");
if(i==3)
numberFiles.insert(1,"1000");
}
}
if(numberParts.size()>1) {
numberFiles.append("point");
if((numberParts.at(1).size()==1) /*|| (numberParts.at(1).toInt()<20)*/)
numberFiles.append(numberParts.at(1));
else {
if(numberParts.at(1).left(1)=="0")
numberFiles.append(numberParts.at(1).left(1));
else
numberFiles.append(numberParts.at(1).left(1)+'0');
numberFiles.append(numberParts.at(1).right(1));
}
}
foreach(QString fileName,numberFiles) {
fileName+=".wav";
QString filePath = QDir::toNativeSeparators(getSoundCollectionPath()+"/"+ getCurrentLanguage()+"/"+fileName);
if(QFile::exists(filePath))
notifyMessageList.insert(position++,QDir::toNativeSeparators(getSoundCollectionPath()+ "/"+getCurrentLanguage()+"/"+fileName));
else {
if(QFile::exists(QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+fileName)))
notifyMessageList.insert(position++,QDir::toNativeSeparators(getSoundCollectionPath()+"/default/"+fileName));
else {
notifyMessageList.clear();
break; // if no some of *.wav files, then don't play number!
}
}
}
}
//str.replace(QString(".wav | .mp3"), QString(""));
return str;
}

View File

@ -1,122 +0,0 @@
/**
******************************************************************************
*
* @file notifypluginconfiguration.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Notify Plugin configuration header
* @see The GNU Public License (GPL) Version 3
* @defgroup notifyplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef NOTIFYPLUGINCONFIGURATION_H
#define NOTIFYPLUGINCONFIGURATION_H
#include <coreplugin/iuavgadgetconfiguration.h>
#include "qsettings.h"
#include <qstringlist.h>
#include <QTimer>
using namespace Core;
class NotifyPluginConfiguration : public QObject
{
Q_OBJECT
public:
explicit NotifyPluginConfiguration(QObject *parent = 0);
QTimer* timer;
QTimer* expireTimer;
bool isNowPlaying; //
bool firstStart;
void copyTo(NotifyPluginConfiguration*) const;
QString getSound1() const { return sound1; }
void setSound1(QString text) {sound1 = text; }
QString getSound2() const { return sound2; }
void setSound2(QString text) {sound2 = text; }
QString getSound3() const { return sound3; }
void setSound3(QString text) {sound3 = text; }
QString getValue() const { return value; }
void setValue(QString text) {value = text; }
QString getSayOrder() const { return sayOrder; }
void setSayOrder(QString text) {sayOrder = text; }
double getSpinBoxValue() const { return spinBoxValue; }
void setSpinBoxValue(double value) {spinBoxValue = value; }
QString getDataObject() const { return dataObject; }
void setDataObject(QString text) {dataObject = text; }
QString getObjectField() const { return objectField; }
void setObjectField(QString text) { objectField = text; }
QString getSoundCollectionPath() const { return soundCollectionPath; }
void setSoundCollectionPath(QString text) { soundCollectionPath = text; }
QString getCurrentLanguage() const { return currentLanguage; }
void setCurrentLanguage(QString text) { currentLanguage = text; }
QStringList getNotifyMessageList() const { return notifyMessageList; }
void setNotifyMessageList(QStringList text) { notifyMessageList = text; }
QString getRepeatFlag() const { return repeatString; }
void setRepeatFlag(QString value) { repeatString = value; }
bool getRepeatTimeout() const { return repeatTimeout; }
void setRepeatTimeout(bool value) { repeatTimeout = value; }
int getExpireTimeout() const { return expireTimeout; }
void setExpireTimeout(int value) { expireTimeout = value; }
void saveState(QSettings* settings) const;
void restoreState(QSettings* settings);
QString parseNotifyMessage();
private:
QStringList notifyMessageList;
QString soundCollectionPath;
QString currentLanguage;
QString dataObject;
QString objectField;
QString value;
QString sound1;
QString sound2;
QString sound3;
QString sayOrder;
double spinBoxValue;
QString repeatString;
bool repeatTimeout;
int repeatTimerValue;
int expireTimeout;
};
Q_DECLARE_METATYPE(NotifyPluginConfiguration*)
#endif // NOTIFYPLUGINCONFIGURATION_H

View File

@ -27,7 +27,7 @@
#include "notifypluginoptionspage.h" #include "notifypluginoptionspage.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include "notifypluginconfiguration.h" #include "notificationitem.h"
#include "ui_notifypluginoptionspage.h" #include "ui_notifypluginoptionspage.h"
#include "extensionsystem/pluginmanager.h" #include "extensionsystem/pluginmanager.h"
#include "utils/pathutils.h" #include "utils/pathutils.h"
@ -39,438 +39,597 @@
#include <QTableWidget> #include <QTableWidget>
#include <QPalette> #include <QPalette>
#include <QBuffer> #include <QBuffer>
#include <QSpinBox>
#include <QLineEdit>
#include "notifyplugin.h" #include "notifyplugin.h"
#include "notifyitemdelegate.h" #include "notifyitemdelegate.h"
#include "notifytablemodel.h" #include "notifytablemodel.h"
#include "notifylogging.h"
NotifyPluginOptionsPage::NotifyPluginOptionsPage(/*NotifyPluginConfiguration *config,*/ QObject *parent) : QStringList NotifyPluginOptionsPage::conditionValues;
IOptionsPage(parent),
owner((SoundNotifyPlugin*)parent), NotifyPluginOptionsPage::NotifyPluginOptionsPage(QObject *parent)
currentCollectionPath(""), : IOptionsPage(parent)
privListNotifications(((SoundNotifyPlugin*)parent)->getListNotifications()) , _objManager(*ExtensionSystem::PluginManager::instance()->getObject<UAVObjectManager>())
, _owner(qobject_cast<SoundNotifyPlugin*>(parent))
, _dynamicFieldCondition(NULL)
, _dynamicFieldWidget(NULL)
, _dynamicFieldType(-1)
, _sayOrder(NULL)
, _form(NULL)
, _selectedNotification(NULL)
{ {
NotifyPluginOptionsPage::conditionValues.insert(equal,tr("Equal to"));
NotifyPluginOptionsPage::conditionValues.insert(bigger,tr("Large than"));
NotifyPluginOptionsPage::conditionValues.insert(smaller,tr("Lower than"));
NotifyPluginOptionsPage::conditionValues.insert(inrange,tr("In range"));
} }
NotifyPluginOptionsPage::~NotifyPluginOptionsPage()
{}
//creates options page widget (uses the UI file)
QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent) QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent)
{ {
_optionsPage.reset(new Ui::NotifyPluginOptionsPage());
//main widget
QWidget* optionsPageWidget = new QWidget;
_dynamicFieldWidget = NULL;
_dynamicFieldCondition = NULL;
resetFieldType();
//save ref to form, needed for binding dynamic fields in future
_form = optionsPageWidget;
//main layout
_optionsPage->setupUi(optionsPageWidget);
options_page = new Ui::NotifyPluginOptionsPage(); _optionsPage->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory);
//main widget _optionsPage->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory"));
QWidget *optionsPageWidget = new QWidget;
//main layout
options_page->setupUi(optionsPageWidget);
delegateItems.clear(); connect(_optionsPage->SoundDirectoryPathChooser, SIGNAL(changed(const QString&)),
listSoundFiles.clear(); this, SLOT(on_clicked_buttonSoundFolder(const QString&)));
connect(_optionsPage->SoundCollectionList, SIGNAL(currentIndexChanged (int)),
this, SLOT(on_changedIndex_soundLanguage(int)));
delegateItems << "Repeat Once" connect(this, SIGNAL(updateNotifications(QList<NotificationItem*>)),
<< "Repeat Instantly" _owner, SLOT(updateNotificationList(QList<NotificationItem*>)));
<< "Repeat 10 seconds" //connect(this, SIGNAL(resetNotification()),owner, SLOT(resetNotification()));
<< "Repeat 30 seconds"
<< "Repeat 1 minute";
options_page->chkEnableSound->setChecked(owner->getEnableSound()); _privListNotifications = _owner->getListNotifications();
options_page->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory);
options_page->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory"));
// [1]
setSelectedNotification(_owner->getCurrentNotification());
addDynamicFieldLayout();
// [2]
updateConfigView(_selectedNotification);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); initRulesTable();
objManager = pm->getObject<UAVObjectManager>(); initButtons();
initPhononPlayer();
// Fills the combo boxes for the UAVObjects int curr_row = _privListNotifications.indexOf(_selectedNotification);
QList< QList<UAVDataObject*> > objList = objManager->getDataObjects(); _notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(curr_row, 0, QModelIndex()),
foreach (QList<UAVDataObject*> list, objList) { QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
foreach (UAVDataObject* obj, list) {
options_page->UAVObject->addItem(obj->getName());
}
}
connect(options_page->SoundDirectoryPathChooser, SIGNAL(changed(const QString&)), this, SLOT(on_buttonSoundFolder_clicked(const QString&))); return optionsPageWidget;
connect(options_page->SoundCollectionList, SIGNAL(currentIndexChanged (int)), this, SLOT(on_soundLanguage_indexChanged(int)));
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->buttonTestSound1, SIGNAL(clicked()), this, SLOT(on_buttonTestSound1_clicked()));
// connect(options_page->buttonTestSound2, SIGNAL(clicked()), this, SLOT(on_buttonTestSound2_clicked()));
connect(options_page->buttonPlayNotification, SIGNAL(clicked()), this, SLOT(on_buttonTestSoundNotification_clicked()));
connect(options_page->chkEnableSound, SIGNAL(toggled(bool)), this, SLOT(on_chkEnableSound_toggled(bool)));
connect(options_page->UAVObject, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVObject_indexChanged(QString)));
connect(this, SIGNAL(updateNotifications(QList<NotifyPluginConfiguration*>)),
owner, SLOT(updateNotificationList(QList<NotifyPluginConfiguration*>)));
connect(this, SIGNAL(resetNotification()),owner, SLOT(resetNotification()));
//emit resetNotification();
privListNotifications.clear();
for (int i = 0; i < owner->getListNotifications().size(); ++i) {
NotifyPluginConfiguration* notification = new NotifyPluginConfiguration();
owner->getListNotifications().at(i)->copyTo(notification);
privListNotifications.append(notification);
}
updateConfigView(owner->getCurrentNotification());
options_page->chkEnableSound->setChecked(owner->getEnableSound());
QStringList headerStrings;
headerStrings << "Name" << "Repeats" << "Lifetime,sec";
notifyRulesModel = new NotifyTableModel(&privListNotifications,headerStrings);
options_page->notifyRulesView->setModel(notifyRulesModel);
options_page->notifyRulesView->resizeRowsToContents();
notifyRulesSelection = new QItemSelectionModel(notifyRulesModel);
connect(notifyRulesSelection, SIGNAL(selectionChanged ( const QItemSelection &, const QItemSelection & )),
this, SLOT(on_tableNotification_changeSelection( const QItemSelection & , const QItemSelection & )));
connect(this, SIGNAL(entryUpdated(int)),
notifyRulesModel, SLOT(entryUpdated(int)));
connect(this, SIGNAL(entryAdded(int)),
notifyRulesModel, SLOT(entryAdded(int)));
options_page->notifyRulesView->setSelectionModel(notifyRulesSelection);
options_page->notifyRulesView->setItemDelegate(new NotifyItemDelegate(delegateItems,this));
options_page->notifyRulesView->setColumnWidth(0,200);
options_page->notifyRulesView->setColumnWidth(1,150);
options_page->notifyRulesView->setColumnWidth(2,100);
options_page->buttonModify->setEnabled(false);
options_page->buttonDelete->setEnabled(false);
options_page->buttonPlayNotification->setEnabled(false);
// sound1 = Phonon::createPlayer(Phonon::NotificationCategory);
// sound2 = Phonon::createPlayer(Phonon::NotificationCategory);
notifySound = Phonon::createPlayer(Phonon::NotificationCategory);
// audioOutput = new Phonon::AudioOutput(Phonon::NotificationCategory, this);
// Phonon::createPath(sound1, audioOutput);
// Phonon::createPath(sound2, audioOutput);
// Phonon::createPath(notifySound, audioOutput);
// connect(sound1,SIGNAL(stateChanged(Phonon::State,Phonon::State)),SLOT(changeButtonText(Phonon::State,Phonon::State)));
// connect(sound2,SIGNAL(stateChanged(Phonon::State,Phonon::State)),SLOT(changeButtonText(Phonon::State,Phonon::State)));
connect(notifySound,SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this,SLOT(changeButtonText(Phonon::State,Phonon::State)));
return optionsPageWidget;
} }
void NotifyPluginOptionsPage::showPersistentComboBox( const QModelIndex & parent, int start, int end )
{
// for (int i=start; i<end+1; i++) {
// options_page->tableNotifications->openPersistentEditor(options_page->tableNotifications->item(i,1));
// }
}
void NotifyPluginOptionsPage::showPersistentComboBox2( const QModelIndex & topLeft, const QModelIndex & bottomRight )
{
//for (QModelIndex i=topLeft; i<bottomRight+1; i++)
{
// options_page->tableNotifications->openPersistentEditor(options_page->tableNotifications->item(options_page->tableNotifications->currentRow(),1));
}
}
void NotifyPluginOptionsPage::getOptionsPageValues(NotifyPluginConfiguration* 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->setSayOrder(options_page->SayOrder->currentText());
notification->setValue(options_page->Value->currentText());
notification->setSpinBoxValue(options_page->ValueSpinBox->value());
// if(notifyRulesSelection->currentIndex().row()>-1)
// {
// //qDebug() << "delegate value:" << options_page->tableNotifications->item(options_page->tableNotifications->currentRow(),1)->data(Qt::EditRole);
// notification->setRepeatFlag(notifyRulesModel->data(notifyRulesSelection->currentIndex(),Qt::DisplayRole).toString());
// }
}
////////////////////////////////////////////
// Called when the user presses apply or OK.
//
// Saves the current values
//
////////////////////////////////////////////
void NotifyPluginOptionsPage::apply() void NotifyPluginOptionsPage::apply()
{ {
getOptionsPageValues(_owner->getCurrentNotification());
getOptionsPageValues(owner->getCurrentNotification()); _owner->setEnableSound(_optionsPage->chkEnableSound->isChecked());
emit updateNotifications(_privListNotifications);
owner->setEnableSound(options_page->chkEnableSound->isChecked());
//owner->setListNotifications(privListNotifications);
emit updateNotifications(privListNotifications);
} }
void NotifyPluginOptionsPage::finish() void NotifyPluginOptionsPage::finish()
{ {
disconnect(notifySound,SIGNAL(stateChanged(Phonon::State,Phonon::State)), disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
this,SLOT(changeButtonText(Phonon::State,Phonon::State))); this, SLOT(on_changedIndex_UAVField(QString)));
if(notifySound)
{
notifySound->stop();
notifySound->clear();
}
delete options_page; disconnect(_testSound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)),
} this,SLOT(on_changed_playButtonText(Phonon::State,Phonon::State)));
if (_testSound) {
_testSound->stop();
_testSound->clear();
//////////////////////////////////////////////////////////////////////////////
// Fills in the <Field> combo box when value is changed in the
// <Object> combo box
//////////////////////////////////////////////////////////////////////////////
void NotifyPluginOptionsPage::on_UAVObject_indexChanged(QString val) {
options_page->UAVObjectField->clear();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>( objManager->getObject(val) );
QList<UAVObjectField*> fieldList = obj->getFields();
foreach (UAVObjectField* field, fieldList) {
options_page->UAVObjectField->addItem(field->getName());
} }
} }
// locate collection folder on disk void NotifyPluginOptionsPage::initButtons()
void NotifyPluginOptionsPage::on_buttonSoundFolder_clicked(const QString& path)
{ {
QDir dirPath(path); _optionsPage->chkEnableSound->setChecked(_owner->getEnableSound());
listDirCollections = dirPath.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); connect(_optionsPage->chkEnableSound, SIGNAL(toggled(bool)),
options_page->SoundCollectionList->clear(); this, SLOT(on_toggled_checkEnableSound(bool)));
options_page->SoundCollectionList->addItems(listDirCollections);
_optionsPage->buttonModify->setEnabled(false);
_optionsPage->buttonDelete->setEnabled(false);
_optionsPage->buttonPlayNotification->setEnabled(false);
connect(_optionsPage->buttonAdd, SIGNAL(pressed()),
this, SLOT(on_clicked_buttonAddNotification()));
connect(_optionsPage->buttonDelete, SIGNAL(pressed()),
this, SLOT(on_clicked_buttonDeleteNotification()));
connect(_optionsPage->buttonModify, SIGNAL(pressed()),
this, SLOT(on_clicked_buttonModifyNotification()));
connect(_optionsPage->buttonPlayNotification, SIGNAL(clicked()),
this, SLOT(on_clicked_buttonTestSoundNotification()));
} }
void NotifyPluginOptionsPage::initPhononPlayer()
void NotifyPluginOptionsPage::on_soundLanguage_indexChanged(int index)
{ {
options_page->SoundCollectionList->setCurrentIndex(index); _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)));
}
currentCollectionPath = options_page->SoundDirectoryPathChooser->path() + void NotifyPluginOptionsPage::initRulesTable()
QDir::toNativeSeparators("/" + options_page->SoundCollectionList->currentText()); {
qNotifyDebug_if(_notifyRulesModel.isNull()) << "_notifyRulesModel.isNull())";
qNotifyDebug_if(!_notifyRulesSelection) << "_notifyRulesSelection.isNull())";
_notifyRulesModel.reset(new NotifyTableModel(_privListNotifications));
_notifyRulesSelection = new QItemSelectionModel(_notifyRulesModel.data());
QDir dirPath(currentCollectionPath); connect(_notifyRulesSelection, SIGNAL(selectionChanged ( const QItemSelection &, const QItemSelection & )),
QStringList filters; this, SLOT(on_changedSelection_notifyTable( const QItemSelection & , const QItemSelection & )));
filters << "*.mp3" << "*.wav"; connect(this, SIGNAL(entryUpdated(int)),
dirPath.setNameFilters(filters); _notifyRulesModel.data(), SLOT(entryUpdated(int)));
listSoundFiles = dirPath.entryList(filters);
listSoundFiles.replaceInStrings(QRegExp(".mp3|.wav"), ""); _optionsPage->notifyRulesView->setModel(_notifyRulesModel.data());
options_page->Sound1->clear(); _optionsPage->notifyRulesView->setSelectionModel(_notifyRulesSelection);
options_page->Sound2->clear(); _optionsPage->notifyRulesView->setItemDelegate(new NotifyItemDelegate(this));
options_page->Sound3->clear();
options_page->Sound1->addItems(listSoundFiles); _optionsPage->notifyRulesView->resizeRowsToContents();
options_page->Sound2->addItem(""); _optionsPage->notifyRulesView->setColumnWidth(eMessageName,200);
options_page->Sound2->addItems(listSoundFiles); _optionsPage->notifyRulesView->setColumnWidth(eRepeatValue,120);
options_page->Sound3->addItem(""); _optionsPage->notifyRulesView->setColumnWidth(eExpireTimer,100);
options_page->Sound3->addItems(listSoundFiles); _optionsPage->notifyRulesView->setColumnWidth(eTurnOn,60);
_optionsPage->notifyRulesView->setDragEnabled(true);
_optionsPage->notifyRulesView->setAcceptDrops(true);
_optionsPage->notifyRulesView->setDropIndicatorShown(true);
_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);
_dynamicFieldCondition = new QComboBox(_form);
_optionsPage->dynamicValueLayout->addWidget(_dynamicFieldCondition);
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(_dynamicFieldCondition, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_changedIndex_rangeValue(QString)));
_dynamicFieldCondition->clear();
_dynamicFieldCondition->addItems(NotifyPluginOptionsPage::conditionValues);
if (UAVObjectField::ENUM == objField->getType()) {
_dynamicFieldCondition->removeItem(smaller);
_dynamicFieldCondition->removeItem(bigger);
}
_dynamicFieldCondition->setCurrentIndex(_dynamicFieldCondition->findText(NotifyPluginOptionsPage::conditionValues.at(_selectedNotification->getCondition())));
connect(_dynamicFieldCondition, 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(_dynamicFieldCondition);
if (NotifyPluginOptionsPage::conditionValues.indexOf(_dynamicFieldCondition->currentText()) == NotifyPluginOptionsPage::inrange) {
_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(-999.99, 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);
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->currentIndex());
notification->setCondition(NotifyPluginOptionsPage::conditionValues.indexOf(_dynamicFieldCondition->currentText()));
if (QDoubleSpinBox* spinValue = dynamic_cast<QDoubleSpinBox*>(_dynamicFieldWidget))
notification->setSingleValue(spinValue->value());
else {
if (QComboBox* comboBoxValue = dynamic_cast<QComboBox*>(_dynamicFieldWidget))
notification->setSingleValue(comboBoxValue->currentText());
else {
if (QLineEdit* rangeValue = dynamic_cast<QLineEdit*>(_dynamicFieldWidget)) {
QString str = rangeValue->text();
QStringList range = str.split(':');
notification->setSingleValue(range.at(0).toDouble());
notification->setValueRange2(range.at(1).toDouble());
}
}
}
}
void NotifyPluginOptionsPage::updateConfigView(NotificationItem* notification)
{
Q_ASSERT(notification);
disconnect(_optionsPage->UAVObject, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_changedIndex_UAVObject(QString)));
disconnect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_changedIndex_UAVField(QString)));
QString path = notification->getSoundCollectionPath();
if (path.isEmpty()) {
path = Utils::PathUtils().InsertDataPath("%%DATAPATH%%sounds");
}
_optionsPage->SoundDirectoryPathChooser->setPath(path);
if (-1 != _optionsPage->SoundCollectionList->findText(notification->getCurrentLanguage())) {
_optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText(notification->getCurrentLanguage()));
} else {
_optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default"));
}
// Fills the combo boxes for the UAVObjects
QList< QList<UAVDataObject*> > objList = _objManager.getDataObjects();
foreach (QList<UAVDataObject*> list, objList) {
foreach (UAVDataObject* obj, list) {
_optionsPage->UAVObject->addItem(obj->getName());
}
}
if (-1 != _optionsPage->UAVObject->findText(notification->getDataObject())) {
_optionsPage->UAVObject->setCurrentIndex(_optionsPage->UAVObject->findText(notification->getDataObject()));
}
_optionsPage->UAVObjectField->clear();
if(_currUAVObject) {
QList<UAVObjectField*> fieldList = _currUAVObject->getFields();
foreach (UAVObjectField* field, fieldList)
_optionsPage->UAVObjectField->addItem(field->getName());
}
if (-1 != _optionsPage->UAVObjectField->findText(notification->getObjectField())) {
_optionsPage->UAVObjectField->setCurrentIndex(_optionsPage->UAVObjectField->findText(notification->getObjectField()));
}
if (-1 != _optionsPage->Sound1->findText(notification->getSound1())) {
_optionsPage->Sound1->setCurrentIndex(_optionsPage->Sound1->findText(notification->getSound1()));
} else {
// show item from default location
_optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default"));
_optionsPage->Sound1->setCurrentIndex(_optionsPage->Sound1->findText(notification->getSound1()));
}
if (-1 != _optionsPage->Sound2->findText(notification->getSound2())) {
_optionsPage->Sound2->setCurrentIndex(_optionsPage->Sound2->findText(notification->getSound2()));
} else {
// show item from default location
_optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default"));
_optionsPage->Sound2->setCurrentIndex(_optionsPage->Sound2->findText(notification->getSound2()));
}
if (-1 != _optionsPage->Sound3->findText(notification->getSound3())) {
_optionsPage->Sound3->setCurrentIndex(_optionsPage->Sound3->findText(notification->getSound3()));
} else {
// show item from default location
_optionsPage->SoundCollectionList->setCurrentIndex(_optionsPage->SoundCollectionList->findText("default"));
_optionsPage->Sound3->setCurrentIndex(_optionsPage->Sound3->findText(notification->getSound3()));
}
_dynamicFieldCondition->setCurrentIndex(_dynamicFieldCondition->findText(NotifyPluginOptionsPage::conditionValues.at(notification->getCondition())));
_sayOrder->setCurrentIndex(notification->getSayOrder());
setDynamicFieldValue(notification);
connect(_optionsPage->UAVObject, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_changedIndex_UAVObject(QString)));
connect(_optionsPage->UAVObjectField, SIGNAL(currentIndexChanged(QString)),
this, SLOT(on_changedIndex_UAVField(QString)));
} }
void NotifyPluginOptionsPage::changeButtonText(Phonon::State newstate, Phonon::State oldstate) void NotifyPluginOptionsPage::on_changedIndex_rangeValue(QString rangeStr)
{ {
if(newstate == Phonon::PausedState || newstate == Phonon::StoppedState){ Q_ASSERT(_dynamicFieldWidget);
options_page->buttonPlayNotification->setText("Play"); UAVObjectField* field = getObjectFieldFromSelected();
options_page->buttonPlayNotification->setIcon(QPixmap(":/notify/images/play.png")); Q_ASSERT(!!field);
} addDynamicFieldWidget(field);
else setDynamicFieldValue(_selectedNotification);
if(newstate == Phonon::PlayingState) {
options_page->buttonPlayNotification->setText("Stop");
options_page->buttonPlayNotification->setIcon(QPixmap(":/notify/images/stop.png"));
}
} }
void NotifyPluginOptionsPage::on_changedIndex_UAVField(QString field)
void NotifyPluginOptionsPage::on_buttonTestSoundNotification_clicked()
{ {
// QList <Phonon::MediaSource> messageNotify; resetFieldType();
NotifyPluginConfiguration *notification; Q_ASSERT(_currUAVObject);
addDynamicField(_currUAVObject->getField(field));
if(notifyRulesSelection->currentIndex().row()==-1) return;
notifySound->clearQueue();
notification = privListNotifications.at(notifyRulesSelection->currentIndex().row());
notification->parseNotifyMessage();
foreach(QString item, notification->getNotifyMessageList())
notifySound->enqueue(Phonon::MediaSource(item));
notifySound->play();
}
void NotifyPluginOptionsPage::on_chkEnableSound_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(NotifyPluginConfiguration* notification)
{
QString path = notification->getSoundCollectionPath();
if(path=="")
{
//QDir dir = QDir::currentPath();
//path = QDir::currentPath().left(QDir::currentPath().indexOf("OpenPilot",0,Qt::CaseSensitive))+"../share/sounds";
path = Utils::PathUtils().InsertDataPath("%%DATAPATH%%sounds");
}
options_page->SoundDirectoryPathChooser->setPath(path);
if(options_page->SoundCollectionList->findText(notification->getCurrentLanguage())!=-1){
options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText(notification->getCurrentLanguage()));
}
else
options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText("default"));
if(options_page->UAVObject->findText(notification->getDataObject())!=-1){
options_page->UAVObject->setCurrentIndex(options_page->UAVObject->findText(notification->getDataObject()));
}
// Now load the object field values:
options_page->UAVObjectField->clear();
QString uavDataObject = notification->getDataObject();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>( objManager->getObject(uavDataObject/*objList.at(0).at(0)->getName()*/) );
if (obj != NULL ) {
QList<UAVObjectField*> fieldList = obj->getFields();
foreach (UAVObjectField* field, fieldList) {
options_page->UAVObjectField->addItem(field->getName());
}
}
if(options_page->UAVObjectField->findText(notification->getObjectField())!=-1){
options_page->UAVObjectField->setCurrentIndex(options_page->UAVObjectField->findText(notification->getObjectField()));
}
if(options_page->Sound1->findText(notification->getSound1())!=-1){
options_page->Sound1->setCurrentIndex(options_page->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()));
// don't show item if it wasn't find in stored location
//options_page->Sound1->setCurrentIndex(-1);
}
if(options_page->Sound2->findText(notification->getSound2())!=-1) {
options_page->Sound2->setCurrentIndex(options_page->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()));
// don't show item if it wasn't find in stored location
//options_page->Sound2->setCurrentIndex(-1);
}
if(options_page->Sound3->findText(notification->getSound3())!=-1) {
options_page->Sound3->setCurrentIndex(options_page->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()));
}
if(options_page->Value->findText(notification->getValue())!=-1) {
options_page->Value->setCurrentIndex(options_page->Value->findText(notification->getValue()));
}
if(options_page->SayOrder->findText(notification->getSayOrder())!=-1) {
options_page->SayOrder->setCurrentIndex(options_page->SayOrder->findText(notification->getSayOrder()));
}
options_page->ValueSpinBox->setValue(notification->getSpinBoxValue());
}
void NotifyPluginOptionsPage::on_tableNotification_changeSelection( const QItemSelection & selected, const QItemSelection & deselected )
{
bool select = true;
notifySound->stop();
if(selected.indexes().size())
updateConfigView(privListNotifications.at(selected.indexes().at(0).row()));
else
select = false;
options_page->buttonModify->setEnabled(select);
options_page->buttonDelete->setEnabled(select);
options_page->buttonPlayNotification->setEnabled(select);
}
void NotifyPluginOptionsPage::on_buttonAddNotification_clicked()
{
NotifyPluginConfiguration* notification = new NotifyPluginConfiguration;
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;
}
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->setValue(options_page->Value->currentText());
notification->setSpinBoxValue(options_page->ValueSpinBox->value());
if(options_page->Sound1->currentText()!="")
notification->setSound1(options_page->Sound1->currentText());
notification->setSound2(options_page->Sound2->currentText());
notification->setSound3(options_page->Sound3->currentText());
if(((options_page->Sound2->currentText()=="")&&(options_page->SayOrder->currentText()=="After second"))
|| ((options_page->Sound3->currentText()=="")&&(options_page->SayOrder->currentText()=="After third")))
return;
else
notification->setSayOrder(options_page->SayOrder->currentText());
privListNotifications.append(notification);
emit entryAdded(privListNotifications.size()-1);
notifyRulesSelection->setCurrentIndex(notifyRulesModel->index(privListNotifications.size()-1,0,QModelIndex()),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
}
void NotifyPluginOptionsPage::on_buttonDeleteNotification_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);
}
} }
void NotifyPluginOptionsPage::on_buttonModifyNotification_clicked() void NotifyPluginOptionsPage::on_changedIndex_UAVObject(QString val)
{ {
NotifyPluginConfiguration* notification = new NotifyPluginConfiguration; resetFieldType();
getOptionsPageValues(notification); _currUAVObject = dynamic_cast<UAVDataObject*>( _objManager.getObject(val) );
notification->setRepeatFlag(privListNotifications.at(notifyRulesSelection->currentIndex().row())->getRepeatFlag()); if(!_currUAVObject) {
privListNotifications.replace(notifyRulesSelection->currentIndex().row(),notification); qNotifyDebug() << "on_UAVObject_indexChanged | no such UAVOBject";
entryUpdated(notifyRulesSelection->currentIndex().row()); 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->addItem("");
_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"));
}
}
}
void NotifyPluginOptionsPage::on_changedSelection_notifyTable(const QItemSelection & selected, const QItemSelection & deselected )
{
bool select = false;
_testSound->stop();
if (selected.indexes().size()) {
select = true;
setSelectedNotification(_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_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;
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");
delete notification;
return;
}
getOptionsPageValues(notification);
if ( ((!_optionsPage->Sound2->currentText().isEmpty()) && (_sayOrder->currentText()=="After second"))
|| ((!_optionsPage->Sound3->currentText().isEmpty()) && (_sayOrder->currentText()=="After third")) ) {
delete notification;
return;
} else {
notification->setSayOrder(_sayOrder->currentIndex());
}
_notifyRulesModel->entryAdded(notification);
_notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(_privListNotifications.size()-1,0,QModelIndex()),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
}
void NotifyPluginOptionsPage::on_clicked_buttonDeleteNotification()
{
_notifyRulesModel->removeRow(_notifyRulesSelection->currentIndex().row());
if (!_notifyRulesModel->rowCount()
&& (_notifyRulesSelection->currentIndex().row() > 0
&& _notifyRulesSelection->currentIndex().row() < _notifyRulesModel->rowCount()) )
{
_optionsPage->buttonDelete->setEnabled(false);
_optionsPage->buttonModify->setEnabled(false);
_optionsPage->buttonPlayNotification->setEnabled(false);
}
}
void NotifyPluginOptionsPage::on_clicked_buttonModifyNotification()
{
NotificationItem* notification = new NotificationItem;
getOptionsPageValues(notification);
notification->setRetryValue(_privListNotifications.at(_notifyRulesSelection->currentIndex().row())->retryValue());
notification->setLifetime(_privListNotifications.at(_notifyRulesSelection->currentIndex().row())->lifetime());
notification->setMute(_privListNotifications.at(_notifyRulesSelection->currentIndex().row())->mute());
_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

@ -0,0 +1,512 @@
/**
******************************************************************************
*
* @file notifypluginoptionspage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Notify Plugin options page
* @see The GNU Public License (GPL) Version 3
* @defgroup notifyplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "notifypluginoptionspage.h"
#include <coreplugin/icore.h>
#include "notificationitem.h"
#include "ui_notifypluginoptionspage.h"
#include "extensionsystem/pluginmanager.h"
#include "utils/pathutils.h"
#include <QFileDialog>
#include <QtAlgorithms>
#include <QStringList>
#include <QtCore/QSettings>
#include <QTableWidget>
#include <QPalette>
#include <QBuffer>
#include "notifyplugin.h"
#include "notifyitemdelegate.h"
#include "notifytablemodel.h"
#include "notifylogging.h"
NotifyPluginOptionsPage::NotifyPluginOptionsPage(/*NotificationItem *config,*/ QObject *parent)
: IOptionsPage(parent)
, objManager(*ExtensionSystem::PluginManager::instance()->getObject<UAVObjectManager>())
, owner(qobject_cast<SoundNotifyPlugin*>(parent))
, currentCollectionPath("")
{
}
NotifyPluginOptionsPage::~NotifyPluginOptionsPage()
{
}
//creates options page widget (uses the UI file)
QWidget *NotifyPluginOptionsPage::createPage(QWidget *parent)
{
options_page.reset(new Ui::NotifyPluginOptionsPage());
//main widget
QWidget *optionsPageWidget = new QWidget;
//main layout
options_page->setupUi(optionsPageWidget);
listSoundFiles.clear();
options_page->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory);
options_page->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory"));
// Fills the combo boxes for the UAVObjects
QList< QList<UAVDataObject*> > objList = objManager.getDataObjects();
foreach (QList<UAVDataObject*> list, objList) {
foreach (UAVDataObject* obj, list) {
options_page->UAVObject->addItem(obj->getName());
}
}
<<<<<<< Updated upstream
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)));
connect(options_page->UAVObject, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVObject_indexChanged(QString)));
=======
options_page = new Ui::NotifyPluginOptionsPage();
//main widget
QWidget *optionsPageWidget = new QWidget;
//main layout
options_page->setupUi(optionsPageWidget);
delegateItems.clear();
listSoundFiles.clear();
options_page->horizontalLayout_3->addWidget(new QPushButton("testtt"));
delegateItems << "Repeat Once"
<< "Repeat Instantly"
<< "Repeat 10 seconds"
<< "Repeat 30 seconds"
<< "Repeat 1 minute";
options_page->chkEnableSound->setChecked(owner->getEnableSound());
options_page->SoundDirectoryPathChooser->setExpectedKind(Utils::PathChooser::Directory);
options_page->SoundDirectoryPathChooser->setPromptDialogTitle(tr("Choose sound collection directory"));
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
objManager = pm->getObject<UAVObjectManager>();
// Fills the combo boxes for the UAVObjects
QList< QList<UAVDataObject*> > objList = objManager->getDataObjects();
foreach (QList<UAVDataObject*> list, objList) {
foreach (UAVDataObject* obj, list) {
options_page->UAVObject->addItem(obj->getName());
}
}
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)));
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->buttonTestSound1, SIGNAL(clicked()), this, SLOT(on_buttonTestSound1_clicked()));
// connect(options_page->buttonTestSound2, SIGNAL(clicked()), this, SLOT(on_buttonTestSound2_clicked()));
connect(options_page->buttonPlayNotification, SIGNAL(clicked()), this, SLOT(on_buttonTestSoundNotification_clicked()));
connect(options_page->chkEnableSound, SIGNAL(toggled(bool)), this, SLOT(on_chkEnableSound_toggled(bool)));
connect(options_page->UAVObject, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_UAVObject_indexChanged(QString)));
connect(this, SIGNAL(updateNotifications(QList<NotifyPluginConfiguration*>)),
owner, SLOT(updateNotificationList(QList<NotifyPluginConfiguration*>)));
connect(this, SIGNAL(resetNotification()),owner, SLOT(resetNotification()));
//emit resetNotification();
privListNotifications.clear();
for (int i = 0; i < owner->getListNotifications().size(); ++i) {
NotifyPluginConfiguration* notification = new NotifyPluginConfiguration();
owner->getListNotifications().at(i)->copyTo(notification);
privListNotifications.append(notification);
}
updateConfigView(owner->getCurrentNotification());
options_page->chkEnableSound->setChecked(owner->getEnableSound());
QStringList headerStrings;
headerStrings << "Name" << "Repeats" << "Lifetime,sec";
>>>>>>> Stashed changes
connect(this, SIGNAL(updateNotifications(QList<NotificationItem*>)),
owner, SLOT(updateNotificationList(QList<NotificationItem*>)));
//connect(this, SIGNAL(resetNotification()),owner, SLOT(resetNotification()));
// privListNotifications = ((qobject_cast<SoundNotifyPlugin*>(parent))->getListNotifications());
privListNotifications = owner->getListNotifications();
updateConfigView(owner->getCurrentNotification());
initRulesTable();
initButtons();
initPhononPlayer();
return optionsPageWidget;
}
void NotifyPluginOptionsPage::initButtons()
{
options_page->chkEnableSound->setChecked(owner->getEnableSound());
connect(options_page->chkEnableSound, SIGNAL(toggled(bool)), this, SLOT(on_chkEnableSound_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()));
}
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)));
}
void NotifyPluginOptionsPage::initRulesTable()
{
qNotifyDebug_if(_notifyRulesModel.isNull()) << "_notifyRulesModel.isNull())";
qNotifyDebug_if(!_notifyRulesSelection) << "_notifyRulesSelection.isNull())";
//QItemSelectionModel* selection = _notifyRulesSelection.take();
_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 & )));
connect(this, SIGNAL(entryUpdated(int)),
_notifyRulesModel.data(), SLOT(entryUpdated(int)));
connect(this, SIGNAL(entryAdded(int)),
_notifyRulesModel.data(), SLOT(entryAdded(int)));
options_page->notifyRulesView->setModel(_notifyRulesModel.data());
options_page->notifyRulesView->setSelectionModel(_notifyRulesSelection);
options_page->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);
}
void NotifyPluginOptionsPage::getOptionsPageValues(NotificationItem* 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->setSayOrder(options_page->SayOrder->currentText());
notification->setValue(options_page->Value->currentText());
notification->setSpinBoxValue(options_page->ValueSpinBox->value());
}
/*!
* Called when the user presses apply or OK.
* Saves the current values
*/
void NotifyPluginOptionsPage::apply()
{
getOptionsPageValues(owner->getCurrentNotification());
owner->setEnableSound(options_page->chkEnableSound->isChecked());
emit updateNotifications(privListNotifications);
}
void NotifyPluginOptionsPage::finish()
{
disconnect(notifySound.data(),SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this,SLOT(changeButtonText(Phonon::State,Phonon::State)));
if (notifySound) {
notifySound->stop();
notifySound->clear();
}
}
//////////////////////////////////////////////////////////////////////////////
// Fills in the <Field> combo box when value is changed in the
// <Object> combo box
//////////////////////////////////////////////////////////////////////////////
void NotifyPluginOptionsPage::on_UAVObject_indexChanged(QString val) {
options_page->UAVObjectField->clear();
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager* objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>( objManager->getObject(val) );
QList<UAVObjectField*> fieldList = obj->getFields();
foreach (UAVObjectField* field, fieldList) {
options_page->UAVObjectField->addItem(field->getName());
}
}
// locate collection folder on disk
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);
}
void NotifyPluginOptionsPage::on_soundLanguage_indexChanged(int index)
{
options_page->SoundCollectionList->setCurrentIndex(index);
currentCollectionPath = options_page->SoundDirectoryPathChooser->path()
+ QDir::toNativeSeparators("/" + options_page->SoundCollectionList->currentText());
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);
}
void NotifyPluginOptionsPage::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"));
} else {
if (newstate == Phonon::PlayingState) {
options_page->buttonPlayNotification->setText("Stop");
options_page->buttonPlayNotification->setIcon(QPixmap(":/notify/images/stop.png"));
}
}
}
void NotifyPluginOptionsPage::onFinishedPlaying()
{
notifySound->clear();
}
void NotifyPluginOptionsPage::on_buttonTestSoundNotification_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());
foreach(QString item, sequence)
notifySound->enqueue(Phonon::MediaSource(item));
notifySound->play();
}
void NotifyPluginOptionsPage::on_chkEnableSound_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)
{
QString path = notification->getSoundCollectionPath();
if (path == "") {
//QDir dir = QDir::currentPath();
//path = QDir::currentPath().left(QDir::currentPath().indexOf("OpenPilot",0,Qt::CaseSensitive))+"../share/sounds";
path = Utils::PathUtils().InsertDataPath("%%DATAPATH%%sounds");
}
options_page->SoundDirectoryPathChooser->setPath(path);
if (-1 != options_page->SoundCollectionList->findText(notification->getCurrentLanguage())){
options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText(notification->getCurrentLanguage()));
} else {
options_page->SoundCollectionList->setCurrentIndex(options_page->SoundCollectionList->findText("default"));
}
if (options_page->UAVObject->findText(notification->getDataObject())!=-1){
options_page->UAVObject->setCurrentIndex(options_page->UAVObject->findText(notification->getDataObject()));
}
// Now load the object field values:
options_page->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) {
options_page->UAVObjectField->addItem(field->getName());
}
}
if (-1 != options_page->UAVObjectField->findText(notification->getObjectField())) {
options_page->UAVObjectField->setCurrentIndex(options_page->UAVObjectField->findText(notification->getObjectField()));
}
if (-1 != options_page->Sound1->findText(notification->getSound1())) {
options_page->Sound1->setCurrentIndex(options_page->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()));
// don't show item if it wasn't find in stored location
//options_page->Sound1->setCurrentIndex(-1);
}
if (-1 != options_page->Sound2->findText(notification->getSound2())) {
options_page->Sound2->setCurrentIndex(options_page->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()));
// don't show item if it wasn't find in stored location
//options_page->Sound2->setCurrentIndex(-1);
}
if (-1 != options_page->Sound3->findText(notification->getSound3())) {
options_page->Sound3->setCurrentIndex(options_page->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()));
}
if (-1 != options_page->Value->findText(notification->getValue())) {
options_page->Value->setCurrentIndex(options_page->Value->findText(notification->getValue()));
}
if (-1 != options_page->SayOrder->findText(notification->getSayOrder())) {
options_page->SayOrder->setCurrentIndex(options_page->SayOrder->findText(notification->getSayOrder()));
}
options_page->ValueSpinBox->setValue(notification->getSpinBoxValue());
}
void NotifyPluginOptionsPage::on_tableNotification_changeSelection( const QItemSelection & selected, const QItemSelection & deselected )
{
bool select = false;
notifySound->stop();
if (selected.indexes().size()) {
select = true;
updateConfigView(privListNotifications.at(selected.indexes().at(0).row()));
}
options_page->buttonModify->setEnabled(select);
options_page->buttonDelete->setEnabled(select);
options_page->buttonPlayNotification->setEnabled(select);
}
void NotifyPluginOptionsPage::on_buttonAddNotification_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;
}
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->setValue(options_page->Value->currentText());
notification->setSpinBoxValue(options_page->ValueSpinBox->value());
if (options_page->Sound1->currentText().size() > 0)
notification->setSound1(options_page->Sound1->currentText());
notification->setSound2(options_page->Sound2->currentText());
notification->setSound3(options_page->Sound3->currentText());
if ( ((!options_page->Sound2->currentText().size()) && (options_page->SayOrder->currentText()=="After second"))
|| ((!options_page->Sound3->currentText().size()) && (options_page->SayOrder->currentText()=="After third")) ) {
return;
} else {
notification->setSayOrder(options_page->SayOrder->currentText());
}
privListNotifications.append(notification);
emit entryAdded(privListNotifications.size() - 1);
_notifyRulesSelection->setCurrentIndex(_notifyRulesModel->index(privListNotifications.size()-1,0,QModelIndex()),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
}
void NotifyPluginOptionsPage::on_buttonDeleteNotification_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);
}
}
void NotifyPluginOptionsPage::on_buttonModifyNotification_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());
privListNotifications.replace(_notifyRulesSelection->currentIndex().row(),notification);
entryUpdated(_notifyRulesSelection->currentIndex().row());
}

View File

@ -42,83 +42,146 @@
#include <phonon/Path> #include <phonon/Path>
#include <phonon/AudioOutput> #include <phonon/AudioOutput>
#include <phonon/Global> #include <phonon/Global>
#include <QComboBox>
#include <QSpinBox>
class NotifyTableModel; class NotifyTableModel;
class NotificationItem;
class NotifyPluginConfiguration;
class SoundNotifyPlugin; class SoundNotifyPlugin;
namespace Ui { namespace Ui {
class NotifyPluginOptionsPage; class NotifyPluginOptionsPage;
} };
using namespace Core; using namespace Core;
class NotifyPluginOptionsPage : public IOptionsPage class NotifyPluginOptionsPage : public IOptionsPage
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit NotifyPluginOptionsPage(/*NotifyPluginConfiguration *config, */QObject *parent = 0); enum {equal,bigger,smaller,inrange};
explicit NotifyPluginOptionsPage(QObject *parent = 0);
QString id() const { return QLatin1String("settings"); } ~NotifyPluginOptionsPage();
QString trName() const { return tr("settings"); } QString id() const { return QLatin1String("settings"); }
QString category() const { return QLatin1String("Notify Plugin");} QString trName() const { return tr("settings"); }
QString trCategory() const { return tr("Notify Plugin");} QString category() const { return QLatin1String("Notify Plugin");}
QString trCategory() const { return tr("Notify Plugin");}
QWidget *createPage(QWidget *parent); QWidget *createPage(QWidget *parent);
void apply(); void apply();
void finish(); void finish();
void restoreFromSettings(); void restoreFromSettings();
static QStringList conditionValues;
void updateConfigView(NotifyPluginConfiguration* notification);
void getOptionsPageValues(NotifyPluginConfiguration* notification);
private:
UAVObjectManager *objManager;
SoundNotifyPlugin* owner;
QStringList listDirCollections;
QStringList listSoundFiles;
QString currentCollectionPath;
int sizeNotifyList;
Phonon::MediaObject *sound1;
Phonon::MediaObject *sound2;
Phonon::MediaObject *notifySound;
Phonon::AudioOutput *audioOutput;
QStringList delegateItems;
NotifyTableModel* notifyRulesModel;
QItemSelectionModel *notifyRulesSelection;
QList<NotifyPluginConfiguration*> privListNotifications;
Ui::NotifyPluginOptionsPage *options_page;
//NotifyPluginConfiguration *notify;
signals: signals:
void updateNotifications(QList<NotifyPluginConfiguration*> list); void updateNotifications(QList<NotificationItem*> list);
void resetNotification(void); void entryUpdated(int index);
void entryUpdated(int index);
void entryAdded(int position);
private slots: private slots:
void showPersistentComboBox( const QModelIndex & parent, int start, int end ); void on_clicked_buttonTestSoundNotification();
void showPersistentComboBox2 ( const QModelIndex & topLeft, const QModelIndex & bottomRight ); void on_clicked_buttonAddNotification();
void on_clicked_buttonDeleteNotification();
void on_clicked_buttonModifyNotification();
// void on_buttonTestSound1_clicked(); /**
// void on_buttonTestSound2_clicked(); * We can use continuous selection, to select simultaneously
void on_buttonTestSoundNotification_clicked(); * multiple rows to move them(using drag & drop) inside table ranges.
*/
void on_changedSelection_notifyTable( const QItemSelection & selected, const QItemSelection & deselected );
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
* 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_changedIndex_rangeValue(QString);
void on_FinishedPlaying(void);
private:
Q_DISABLE_COPY(NotifyPluginOptionsPage)
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;
//! Media object uses to test sound playing
QScopedPointer<Phonon::MediaObject> _testSound;
QScopedPointer<NotifyTableModel> _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<NotificationItem*> _privListNotifications;
QScopedPointer<Ui::NotifyPluginOptionsPage> _optionsPage;
//! Widget to convinient selection of condition for field value (equal, lower, greater)
QComboBox* _dynamicFieldCondition;
//! 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;
//! 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;
//! 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;
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 changeButtonText(Phonon::State newstate, Phonon::State oldstate);
void on_chkEnableSound_toggled(bool state);
}; };
#endif // NOTIFYPLUGINOPTIONSPAGE_H #endif // NOTIFYPLUGINOPTIONSPAGE_H

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>589</width> <width>570</width>
<height>453</height> <height>453</height>
</rect> </rect>
</property> </property>
@ -19,531 +19,364 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<widget class="QGroupBox" name="groupBox_2"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="geometry"> <property name="sizeConstraint">
<rect> <enum>QLayout::SetMinimumSize</enum>
<x>10</x>
<y>10</y>
<width>501</width>
<height>81</height>
</rect>
</property> </property>
<property name="title"> <item>
<string>Sound Collection</string> <layout class="QVBoxLayout" name="verticalLayout_2">
</property> <property name="sizeConstraint">
<widget class="QWidget" name="layoutWidget_2"> <enum>QLayout::SetFixedSize</enum>
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>481</width>
<height>51</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="spacing">
<number>6</number>
</property> </property>
<item row="1" column="0"> <item>
<widget class="QLabel" name="labelLanguage"> <widget class="QGroupBox" name="groupBox_2">
<property name="text"> <property name="sizePolicy">
<string>Language</string> <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
</widget> <property name="title">
</item> <string>Sound Collection</string>
<item row="0" column="0" colspan="5">
<widget class="Utils::PathChooser" name="SoundDirectoryPathChooser" native="true">
<property name="enabled">
<bool>true</bool>
</property> </property>
<property name="minimumSize"> <layout class="QGridLayout" name="gridLayout">
<size> <item row="0" column="0" colspan="2">
<width>75</width> <widget class="Utils::PathChooser" name="SoundDirectoryPathChooser" native="true">
<height>23</height> <property name="enabled">
</size> <bool>true</bool>
</property> </property>
</widget> <property name="minimumSize">
</item> <size>
<item row="1" column="1" colspan="4"> <width>75</width>
<widget class="QComboBox" name="SoundCollectionList"> <height>23</height>
<property name="minimumSize"> </size>
<size> </property>
<width>147</width> <property name="maximumSize">
<height>0</height> <size>
</size> <width>550</width>
</property> <height>16777215</height>
<property name="toolTip"> </size>
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; </property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelLanguage">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="SoundCollectionList">
<property name="minimumSize">
<size>
<width>147</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Select the sound collection&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Select the sound collection&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
</item>
<item>
<layout class="QHBoxLayout" name="uavObjectLayout">
<item>
<widget class="QLabel" name="labelDataOb">
<property name="text">
<string>DataObject</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="UAVObject">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelObjectField">
<property name="text">
<string>ObjectField</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="UAVObjectField">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </item>
</widget> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="Line" name="line">
<property name="geometry"> <property name="orientation">
<rect> <enum>Qt::Horizontal</enum>
<x>10</x> </property>
<y>220</y> </widget>
<width>501</width> </item>
<height>211</height> <item>
</rect> <layout class="QHBoxLayout" name="dynamicValueLayout"/>
</property> </item>
<property name="title"> <item>
<string>Sound Notifications</string> <layout class="QHBoxLayout" name="soundsLayout">
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>180</y>
<width>481</width>
<height>26</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QCheckBox" name="chkEnableSound"> <widget class="QLabel" name="labelSound1">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>Enable Sounds</string> <string>Sound1:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_2"> <widget class="QComboBox" name="Sound1">
<property name="orientation"> <property name="sizePolicy">
<enum>Qt::Horizontal</enum> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="minimumSize">
<size> <size>
<width>138</width> <width>110</width>
<height>20</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> <property name="maximumSize">
</item>
<item>
<widget class="QPushButton" name="buttonPlayNotification">
<property name="text">
<string>Play</string>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/notify/images/play.png</normaloff>:/notify/images/play.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>16777215</width>
<height>20</height> <height>16777215</height>
</size> </size>
</property> </property>
</spacer> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_3"> <widget class="QLabel" name="labelSound2">
<property name="orientation"> <property name="sizePolicy">
<enum>Qt::Horizontal</enum> <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="text">
<string>Sound2:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="Sound2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size> <size>
<width>40</width> <width>110</width>
<height>20</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> <property name="maximumSize">
</item> <size>
<item> <width>16777215</width>
<widget class="QPushButton" name="buttonAdd"> <height>16777215</height>
<property name="text"> </size>
<string>Add</string>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/notify/images/add.png</normaloff>:/notify/images/add.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="buttonModify"> <widget class="QLabel" name="labelSound3">
<property name="text"> <property name="sizePolicy">
<string>Modify</string> <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="icon"> <property name="text">
<iconset resource="res.qrc"> <string>Sound3:</string>
<normaloff>:/notify/images/modify.png</normaloff>:/notify/images/modify.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="buttonDelete"> <widget class="QComboBox" name="Sound3">
<property name="text"> <property name="sizePolicy">
<string>Delete</string> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="icon"> <property name="minimumSize">
<iconset resource="../../libs/utils/utils.qrc"> <size>
<normaloff>:/utils/images/removesubmitfield.png</normaloff>:/utils/images/removesubmitfield.png</iconset> <width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </item>
<widget class="QTableView" name="notifyRulesView"> <item>
<property name="geometry"> <layout class="QVBoxLayout" name="verticalLayout_3"/>
<rect> </item>
<x>10</x> <item>
<y>20</y> <widget class="QGroupBox" name="groupBox">
<width>481</width> <property name="title">
<height>151</height> <string>Sound Notifications</string>
</rect> </property>
</property> <layout class="QVBoxLayout" name="verticalLayout_4">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="verticalHeaderDefaultSectionSize">
<number>22</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>22</number>
</attribute>
</widget>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>501</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="labelDataOb">
<property name="text">
<string>DataObject</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="UAVObject">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelObjectField">
<property name="text">
<string>ObjectField</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="UAVObjectField">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>7</x>
<y>130</y>
<width>501</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_2">
<property name="geometry">
<rect>
<x>10</x>
<y>180</y>
<width>501</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="labelSound1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Sound1:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="Sound1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSound2">
<property name="text">
<string>Sound2:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="Sound2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSound3">
<property name="text">
<string>Sound3:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="Sound3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_3">
<property name="geometry">
<rect>
<x>10</x>
<y>150</y>
<width>501</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="labelValue">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Value is</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="Value">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<item> <item>
<property name="text"> <widget class="QTableView" name="notifyRulesView">
<string>Equal to</string> <property name="selectionMode">
</property> <enum>QAbstractItemView::ContiguousSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="verticalHeaderDefaultSectionSize">
<number>22</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>22</number>
</attribute>
</widget>
</item> </item>
<item> <item>
<property name="text"> <layout class="QHBoxLayout" name="horizontalLayout">
<string>Greater than</string> <item>
</property> <widget class="QCheckBox" name="chkEnableSound">
<property name="text">
<string>Enable Sounds</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>138</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonPlayNotification">
<property name="text">
<string>Play</string>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/notify/images/play.png</normaloff>:/notify/images/play.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonAdd">
<property name="text">
<string>Add</string>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/notify/images/add.png</normaloff>:/notify/images/add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonModify">
<property name="text">
<string>Modify</string>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/notify/images/modify.png</normaloff>:/notify/images/modify.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonDelete">
<property name="text">
<string>Delete</string>
</property>
<property name="icon">
<iconset resource="../../libs/utils/utils.qrc">
<normaloff>:/utils/images/removesubmitfield.png</normaloff>:/utils/images/removesubmitfield.png</iconset>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> </layout>
<property name="text"> </widget>
<string>Less than</string> </item>
</property> </layout>
</item>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="ValueSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>9999.899999999999636</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSayOrder">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Say Order</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="SayOrder">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Select if the value of the object should be spoken and if so, either before the configured sound or after it.</string>
</property>
<item>
<property name="text">
<string>Never</string>
</property>
</item>
<item>
<property name="text">
<string>Before first</string>
</property>
</item>
<item>
<property name="text">
<string>After first</string>
</property>
</item>
<item>
<property name="text">
<string>After second</string>
</property>
</item>
<item>
<property name="text">
<string>After third</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -26,110 +26,239 @@
*/ */
#include "notifytablemodel.h" #include "notifytablemodel.h"
#include "notifylogging.h"
#include <qdebug.h>
#include <QMimeData>
const char* mime_type_notify_table = "openpilot/notify_plugin_table";
NotifyTableModel::NotifyTableModel(QList<NotificationItem*>& parentList, QObject* parent)
: QAbstractTableModel(parent)
, _list(parentList)
{
_headerStrings << "Name" << "Repeats" << "Lifetime,sec" << "Mute";
connect(this, SIGNAL(dragRows(int, int)), this, SLOT(dropRows(int, int)));
}
bool NotifyTableModel::setData(const QModelIndex &index, bool NotifyTableModel::setData(const QModelIndex &index,
const QVariant &value, int role) const QVariant &value, int role)
{ {
if (index.isValid() && role == Qt::EditRole) { if (index.isValid() && role == Qt::DisplayRole) {
if(index.column()==1) if (eMessageName == index.column()) {
_list->at(index.row())->setRepeatFlag(value.toString()); emit dataChanged(index, index);
else return true;
if(index.column()==2) }
_list->at(index.row())->setExpireTimeout(value.toInt()); }
if (index.isValid() && role == Qt::EditRole) {
emit dataChanged(index, index); if (eRepeatValue == index.column())
return true; _list.at(index.row())->setRetryValue(NotificationItem::retryValues.indexOf(value.toString()));
} else {
return false; if (eExpireTimer == index.column())
_list.at(index.row())->setLifetime(value.toInt());
else {
if (eTurnOn == index.column())
_list.at(index.row())->setMute(value.toBool());
}
}
emit dataChanged(index, index);
return true;
}
return false;
} }
QVariant NotifyTableModel::data(const QModelIndex &index, int role) const QVariant NotifyTableModel::data(const QModelIndex &index, int role) const
{ {
if (!index.isValid()) {
qWarning() << "NotifyTableModel::data - index.isValid()";
return QVariant();
}
if (!index.isValid()) if (index.row() >= _list.size())
return QVariant(); return QVariant();
if (index.row() >= _list->size()) if (role == Qt::DisplayRole || role == Qt::EditRole)
return QVariant(); {
switch(index.column())
{
case eMessageName:
return _list.at(index.row())->toString();
if (role == Qt::DisplayRole || role == Qt::EditRole) case eRepeatValue:
{ return (NotificationItem::retryValues.at(_list.at(index.row())->retryValue()));
switch(index.column())
{
case 0:
return _list->at(index.row())->parseNotifyMessage();
case 1: case eExpireTimer:
return _list->at(index.row())->getRepeatFlag(); return _list.at(index.row())->lifetime();
case 2: case eTurnOn:
return _list->at(index.row())->getExpireTimeout(); return _list.at(index.row())->mute();
default: default:
return QVariant(); return QVariant();
} }
} }
else else
{ {
if (Qt::SizeHintRole == role){ if (Qt::SizeHintRole == role){
//QVariant size = data(index, Qt::SizeHintRole); return QVariant(10);
return QVariant(10); }
} }
// if(role == Qt::DecorationRole) return QVariant();
// if (index.column() == 0)
// return defectsIcons[defectList->at(index.row()).id-1];
}
return QVariant();
} }
QVariant NotifyTableModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant NotifyTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{ {
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
if (orientation == Qt::Horizontal) if (orientation == Qt::Horizontal)
return headerStrings.at(section); return _headerStrings.at(section);
else else
if(orientation == Qt::Vertical) if (orientation == Qt::Vertical)
return QString("%1").arg(section); return QString("%1").arg(section);
return QVariant(); return QVariant();
} }
bool NotifyTableModel::insertRows(int position, int rows, const QModelIndex &index) bool NotifyTableModel::insertRows(int position, int rows, const QModelIndex& index)
{ {
Q_UNUSED(index); Q_UNUSED(index);
beginInsertRows(QModelIndex(), position, position+rows-1);
// for (int row=0; row < rows; ++row) { if (-1 == position || -1 == rows)
// _list->append(position); return false;
// }
beginInsertRows(QModelIndex(), position, position + rows - 1);
endInsertRows(); for (int i = 0; i < rows; ++i) {
return true; _list.insert(position + i, new NotificationItem());
}
endInsertRows();
return true;
} }
bool NotifyTableModel::removeRows(int position, int rows, const QModelIndex &index) bool NotifyTableModel::removeRows(int position, int rows, const QModelIndex& index)
{ {
Q_UNUSED(index); Q_UNUSED(index);
beginRemoveRows(QModelIndex(), position, position+rows-1);
for (int row=0; row < rows; ++row) { if ((-1 == position) || (-1 == rows) )
_list->removeAt(position); return false;
}
endRemoveRows(); beginRemoveRows(QModelIndex(), position, position + rows - 1);
return true;
} for (int row = 0; row < rows; ++row) {
_list.removeAt(position);
}
endRemoveRows();
return true;
}
void NotifyTableModel::entryUpdated(int offset) void NotifyTableModel::entryUpdated(int offset)
{ {
QModelIndex idx = index(offset, 0); QModelIndex idx = index(offset, 0);
emit dataChanged(idx, idx); emit dataChanged(idx, idx);
} }
void NotifyTableModel::entryAdded(int position) void NotifyTableModel::entryAdded(NotificationItem* item)
{ {
insertRows(position, 1,QModelIndex()); insertRows(rowCount(), 1, QModelIndex());
NotificationItem* tmp = _list.at(rowCount() - 1);
_list.replace(rowCount() - 1, item);
delete tmp;
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)
{
if (action == Qt::IgnoreAction)
return true;
if (!data->hasFormat(mime_type_notify_table))
return false;
int beginRow = -1;
if (row != -1)
beginRow = row;
else {
if (parent.isValid())
beginRow = parent.row();
else
beginRow = rowCount(QModelIndex());
}
if (-1 == beginRow)
return false;
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<NotificationItem*>(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);
// check drop bounds
if (dragged < 0 || ((dragged + 1) >= _list.size() && direction == DOWN_DIRECTION) || dragged == rows) {
qNotifyDebug() << "no such item";
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)
++rows;
};
QModelIndex idxTopLeft = index(beginRow, 0, QModelIndex());
QModelIndex idxBotRight = index(beginRow, columnCount(QModelIndex()), QModelIndex());
emit dataChanged(idxTopLeft, idxBotRight);
return true;
}
QMimeData* NotifyTableModel::mimeData(const QModelIndexList& indexes) const
{
QMimeData* mimeData = new QMimeData();
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
int rows = 0;
foreach (const QModelIndex& index, indexes) {
if (!index.column()) {
qint32 item = reinterpret_cast<qint32>(_list.at(index.row()));
stream << item;
++rows;
}
}
mimeData->setData(mime_type_notify_table, encodedData);
return mimeData;
}
void NotifyTableModel::dropRows(int position, int count) const
{
for (int row = 0; row < count; ++row) {
_list.removeAt(position);
}
} }

View File

@ -31,49 +31,60 @@
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QList> #include <QList>
#include "notifypluginconfiguration.h" #include "notificationitem.h"
enum ColumnNames { eMessageName, eRepeatValue, eExpireTimer, eTurnOn };
class NotifyTableModel : public QAbstractTableModel class NotifyTableModel : public QAbstractTableModel
{ {
Q_OBJECT Q_OBJECT
public:
NotifyTableModel(QList<NotifyPluginConfiguration*> *parentList, const QStringList& parentHeaderList, QObject *parent = 0)
: QAbstractTableModel(parent),
_list(parentList),
headerStrings(parentHeaderList)
{ }
int rowCount(const QModelIndex &parent = QModelIndex()) const enum {eColumnCount = 4 };
{
return _list->count();
}
int columnCount(const QModelIndex &/*parent*/) const public:
{
return 3;
}
Qt::ItemFlags flags(const QModelIndex &index) const NotifyTableModel(QList<NotificationItem*>& parentList, QObject* parent = 0);
{ int rowCount(const QModelIndex& parent = QModelIndex()) const
if (!index.isValid()) {
return Qt::ItemIsEnabled; return _list.count();
}
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; int columnCount(const QModelIndex &/*parent*/) const
} {
return eColumnCount;
}
bool setData(const QModelIndex &index, const QVariant &value, int role); Qt::ItemFlags flags(const QModelIndex &index) const
QVariant data(const QModelIndex &index, int role) const; {
QVariant headerData(int section, Qt::Orientation orientation, int role) const; if (!index.isValid())
bool insertRows(int position, int rows, const QModelIndex &index); return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled;
bool removeRows(int position, int rows, const QModelIndex &index);
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);
signals:
void dragRows(int position, int count);
private slots: private slots:
void entryUpdated(int offset); void entryUpdated(int offset);
void entryAdded(int position); void dropRows(int position, int count) const;
private: private:
QList<NotifyPluginConfiguration*> *_list; mutable QList<NotificationItem*>& _list;
QStringList headerStrings; QStringList _headerStrings;
}; };
#endif // NOTIFYTABLEMODEL_H #endif // NOTIFYTABLEMODEL_H