Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / ground / gcs / src / plugins / notify / notificationitem.cpp
blob4d47c7b2a8a42ab93b659f275114a17b8d33aa7a
1 /**
2 ******************************************************************************
4 * @file NotificationItem.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @brief Notify Plugin configuration
7 * @see The GNU Public License (GPL) Version 3
8 * @defgroup notifyplugin
9 * @{
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // Qt headers
29 #include <QDataStream>
30 #include <QDir>
31 #include <QFile>
33 // GCS headers
34 #include "extensionsystem/pluginmanager.h"
35 #include "utils/pathutils.h"
36 #include "uavobjectmanager.h"
37 #include "uavobject.h"
39 // Notify plugin headers
40 #include "notificationitem.h"
41 #include "notifylogging.h"
44 QStringList NotificationItem::sayOrderValues;
45 QStringList NotificationItem::retryValues;
48 NotificationItem::NotificationItem(QObject *parent)
49 : QObject(parent)
50 , isNowPlaying(0)
51 , _isPlayed(false)
52 , _currentUpdatePlayed(false)
53 , _timer(NULL)
54 , _expireTimer(NULL)
55 , _soundCollectionPath("")
56 , _currentLanguage("default")
57 , _dataObject("")
58 , _objectField("")
59 , _condition(0)
60 , _sound1("")
61 , _sound2("")
62 , _sound3("")
63 , _sayOrder(never)
64 , _singleValue(0)
65 , _valueRange2(0)
66 , _repeatValue(repeatInstantly)
67 , _expireTimeout(eDefaultTimeout)
68 , _mute(false)
70 NotificationItem::sayOrderValues.clear();
71 NotificationItem::sayOrderValues.insert(never, QString(tr("Never")));
72 NotificationItem::sayOrderValues.insert(beforeFirst, QString(tr("Before first")));
73 NotificationItem::sayOrderValues.insert(beforeSecond, QString(tr("Before second")));
74 NotificationItem::sayOrderValues.insert(afterSecond, QString(tr("After second")));
76 NotificationItem::retryValues.clear();
77 NotificationItem::retryValues.insert(repeatOnce, QString(tr("Repeat Once")));
78 NotificationItem::retryValues.insert(repeatOncePerUpdate, QString(tr("Repeat Once per update")));
79 NotificationItem::retryValues.insert(repeatInstantly, QString(tr("Repeat Instantly")));
80 NotificationItem::retryValues.insert(repeat10seconds, QString(tr("Repeat 10 seconds")));
81 NotificationItem::retryValues.insert(repeat30seconds, QString(tr("Repeat 30 seconds")));
82 NotificationItem::retryValues.insert(repeat1minute, QString(tr("Repeat 1 minute")));
85 void NotificationItem::copyTo(NotificationItem *that) const
87 that->isNowPlaying = isNowPlaying;
88 that->_isPlayed = _isPlayed;
89 that->_soundCollectionPath = _soundCollectionPath;
90 that->_currentLanguage = _currentLanguage;
91 that->_soundCollectionPath = _soundCollectionPath;
92 that->_dataObject = _dataObject;
93 that->_objectField = _objectField;
94 that->_condition = _condition;
95 that->_sound1 = _sound1;
96 that->_sound2 = _sound2;
97 that->_sound3 = _sound3;
98 that->_sayOrder = _sayOrder;
99 that->_singleValue = _singleValue;
100 that->_valueRange2 = _valueRange2;
101 that->_repeatValue = _repeatValue;
102 that->_expireTimeout = _expireTimeout;
103 that->_mute = _mute;
107 void NotificationItem::saveState(QSettings &settings) const
109 settings.setValue("SoundCollectionPath", Utils::RemoveDataPath(getSoundCollectionPath()));
110 settings.setValue(QLatin1String("CurrentLanguage"), getCurrentLanguage());
111 settings.setValue(QLatin1String("ObjectField"), getObjectField());
112 settings.setValue(QLatin1String("DataObject"), getDataObject());
113 settings.setValue(QLatin1String("RangeLimit"), getCondition());
114 settings.setValue(QLatin1String("Value1"), singleValue());
115 settings.setValue(QLatin1String("Value2"), valueRange2());
116 settings.setValue(QLatin1String("Sound1"), getSound1());
117 settings.setValue(QLatin1String("Sound2"), getSound2());
118 settings.setValue(QLatin1String("Sound3"), getSound3());
119 settings.setValue(QLatin1String("SayOrder"), getSayOrder());
120 settings.setValue(QLatin1String("Repeat"), retryValue());
121 settings.setValue(QLatin1String("ExpireTimeout"), lifetime());
122 settings.setValue(QLatin1String("Mute"), mute());
125 void NotificationItem::restoreState(QSettings &settings)
127 // settings = Core::ICore::instance()->settings();
128 setSoundCollectionPath(Utils::InsertDataPath(settings.value(QLatin1String("SoundCollectionPath"), tr("")).toString()));
129 setCurrentLanguage(settings.value(QLatin1String("CurrentLanguage"), tr("")).toString());
130 setDataObject(settings.value(QLatin1String("DataObject"), tr("")).toString());
131 setObjectField(settings.value(QLatin1String("ObjectField"), tr("")).toString());
132 setCondition(settings.value(QLatin1String("RangeLimit"), tr("")).toInt());
133 setSound1(settings.value(QLatin1String("Sound1"), tr("")).toString());
134 setSound2(settings.value(QLatin1String("Sound2"), tr("")).toString());
135 setSound3(settings.value(QLatin1String("Sound3"), tr("")).toString());
136 setSayOrder(settings.value(QLatin1String("SayOrder"), tr("")).toInt());
137 QVariant value = settings.value(QLatin1String("Value1"), tr(""));
138 setSingleValue(value);
139 setValueRange2(settings.value(QLatin1String("Value2"), tr("")).toDouble());
140 setRetryValue(settings.value(QLatin1String("Repeat"), tr("")).toInt());
141 setLifetime(settings.value(QLatin1String("ExpireTimeout"), tr("")).toInt());
142 setMute(settings.value(QLatin1String("Mute"), tr("")).toInt());
145 void NotificationItem::serialize(QDataStream & stream)
147 stream << this->_soundCollectionPath;
148 stream << this->_currentLanguage;
149 stream << this->_dataObject;
150 stream << this->_objectField;
151 stream << this->_condition;
152 qNotifyDebug() << "getOptionsPageValues serialize" << _condition;
153 stream << this->_sound1;
154 stream << this->_sound2;
155 stream << this->_sound3;
156 stream << this->_sayOrder;
157 stream << this->_singleValue;
158 stream << this->_valueRange2;
159 stream << this->_repeatValue;
160 stream << this->_expireTimeout;
161 stream << this->_mute;
164 void NotificationItem::deserialize(QDataStream & stream)
166 stream >> this->_soundCollectionPath;
167 stream >> this->_currentLanguage;
168 stream >> this->_dataObject;
169 stream >> this->_objectField;
170 stream >> this->_condition;
171 stream >> this->_sound1;
172 stream >> this->_sound2;
173 stream >> this->_sound3;
174 stream >> this->_sayOrder;
175 stream >> this->_singleValue;
176 stream >> this->_valueRange2;
177 stream >> this->_repeatValue;
178 stream >> this->_expireTimeout;
179 stream >> this->_mute;
182 void NotificationItem::startTimer(int msec)
184 if (!_timer) {
185 _timer = new QTimer(this);
186 _timer->setInterval(msec);
188 if (!_timer->isActive()) {
189 _timer->start();
194 void NotificationItem::restartTimer()
196 if (!_timer) {
197 if (!_timer->isActive()) {
198 _timer->start();
204 void NotificationItem::stopTimer()
206 if (_timer) {
207 if (_timer->isActive()) {
208 _timer->stop();
213 void NotificationItem::disposeTimer()
215 if (_timer) {
216 _timer->stop();
217 delete _timer;
218 _timer = NULL;
222 void NotificationItem::startExpireTimer()
224 if (!_expireTimer) {
225 _expireTimer = new QTimer(this);
227 _expireTimer->start(_expireTimeout * 1000);
230 void NotificationItem::stopExpireTimer()
232 if (_expireTimer) {
233 if (_expireTimer) {
234 _expireTimer->stop();
239 void NotificationItem::disposeExpireTimer()
241 if (_expireTimer) {
242 _expireTimer->stop();
243 delete _expireTimer;
244 _expireTimer = NULL;
248 int getValuePosition(QString sayOrder)
250 return NotificationItem::sayOrderValues.indexOf(sayOrder) - 1;
253 QString NotificationItem::checkSoundExists(QString fileName)
255 QString name(fileName + ".wav");
256 QString filePath = QDir::toNativeSeparators(getSoundCollectionPath() + "/" +
257 getCurrentLanguage() + "/" +
258 name);
260 if (QFile::exists(filePath)) {
261 return filePath;
262 } else {
263 filePath = QDir::toNativeSeparators(getSoundCollectionPath() +
264 "/default/" +
265 name);
266 if (!QFile::exists(filePath)) {
267 filePath.clear();
270 return filePath;
273 QStringList valueToSoundList(QString value)
275 qNotifyDebug() << "notificationItem valueToSoundList input param" << value;
276 // replace point chr if exists
277 value = value.replace(',', '.');
278 QStringList numberParts = value.trimmed().split(".");
279 QStringList digitWavs;
280 bool negative = false;
281 if (numberParts.at(0).toInt() < 0) {
282 negative = true;
283 digitWavs.append("minus");
284 numberParts[0] = QString::number(numberParts.at(0).toInt() * -1);
286 if ((numberParts.at(0).size() == 1) || (numberParts.at(0).toInt() < 20)) {
287 // [1] check, is this number < 20, these numbers played by one wav file
288 digitWavs.append(numberParts.at(0));
289 } else {
290 int i = 0;
291 // [2] store two lowest digits of number
292 int num = numberParts.at(0).right(2).toInt();
293 if (num < 20 && num != 0) {
294 // store eighter number in range [0...10) or in range [10...20)
295 digitWavs.append(numberParts.at(0).right(1 + num / 11));
296 i = 2;
298 // [3] prepend 100 and 1000 digits of number
299 for (; i < numberParts.at(0).size(); i++) {
300 int offset = 0;
301 if (negative) {
302 offset = 1;
304 digitWavs.insert(offset, numberParts.at(0).at(numberParts.at(0).size() - i - 1));
305 if (digitWavs.at(offset) == QString("0")) {
306 digitWavs.removeAt(offset);
307 continue;
309 if (i == 1) {
310 digitWavs.replace(0 + offset, digitWavs.at(offset) + '0');
312 if (i == 2) {
313 digitWavs.insert(1 + offset, "100");
315 if (i == 3) {
316 digitWavs.insert(1 + offset, "1000");
320 // check, is there fractional part of number?
321 if (1 < numberParts.size()) {
322 digitWavs.append("point");
323 if (numberParts.at(1).size() == 1) {
324 // this mean -> number < 1
325 digitWavs.append(numberParts.at(1));
326 } else {
327 // append fractional part of number
328 QString left = numberParts.at(1).left(1);
329 (left == "0") ? digitWavs.append(left) : digitWavs.append(left + '0');
330 digitWavs.append(numberParts.at(1).right(1));
333 qNotifyDebug() << "notificationItem valueToSoundList return value" << digitWavs;
334 return digitWavs;
337 QString stringFromValue(QVariant value, UAVObjectField *field)
339 if (field == NULL) {
340 return "";
342 Q_ASSERT(field);
343 Q_ASSERT(!value.isNull());
344 QString str;
345 if (UAVObjectField::ENUM == field->getType()) {
346 if (!field->getOptions().contains(value.toString())) {
347 return QString();
349 str = value.toString();
350 } else {
351 str = QString("%L1").arg(value.toDouble());
353 return str;
356 QString NotificationItem::toString()
358 QString str;
359 UAVObjectField *field = getUAVObjectField();
360 QString value = stringFromValue(singleValue(), field);
362 int pos = getSayOrder() - 1;
363 QStringList lst;
365 lst.append(getSoundCaption(getSound1()));
366 lst.append(getSoundCaption(getSound2()));
367 lst.append(getSoundCaption(getSound3()));
368 QStringList valueSounds = valueToSoundList(value);
369 bool missed = false;
370 foreach(QString sound, valueSounds) {
371 if (checkSoundExists(sound).isEmpty()) {
372 missed = true;
373 break;
377 // if not "Never" case
378 if (-1 != pos) {
379 if (missed) {
380 lst.insert(pos, "[missed]" + value);
381 } else {
382 lst.insert(pos, value);
385 str = lst.join(" ");
386 return str;
389 QStringList & NotificationItem::toSoundList()
391 // tips:
392 // check of *.wav files exist needed for playing phonon queues;
393 // if phonon player don't find next file in queue, it buzz
394 UAVObjectField *field = getUAVObjectField();
395 QString value = stringFromValue(singleValue(), field);
397 // generate queue of sound files to play
398 _messageSequence.clear();
399 int pos = getSayOrder() - 1;
400 QStringList lst;
401 if (!getSound1().isEmpty()) {
402 lst.append(getSound1());
404 if (!getSound2().isEmpty()) {
405 lst.append(getSound2());
407 if (!getSound3().isEmpty()) {
408 lst.append(getSound3());
411 // if not "Never" case
412 if (-1 != pos) {
413 QStringList valueSounds = valueToSoundList(value);
414 foreach(QString sound, valueSounds)
415 lst.insert(pos++, sound);
418 foreach(QString sound, lst) {
419 QString path = checkSoundExists(sound);
421 if (!path.isEmpty()) {
422 _messageSequence.append(path);
423 } else {
424 _messageSequence.clear();
425 break;
428 return _messageSequence;
431 QString NotificationItem::getSoundCaption(QString fileName)
433 if (fileName.isEmpty()) {
434 return QString();
436 if (checkSoundExists(fileName).isEmpty()) {
437 return QString("[missed]") + fileName;
439 return fileName;
442 UAVObjectField *NotificationItem::getUAVObjectField()
444 return getUAVObject()->getField(getObjectField());
447 UAVDataObject *NotificationItem::getUAVObject()
449 return dynamic_cast<UAVDataObject *>((ExtensionSystem::PluginManager::instance()->getObject<UAVObjectManager>())->getObject(getDataObject()));