diff --git a/INSTALL.md b/INSTALL.md index 7551fcd..e7be4dd 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -7,19 +7,26 @@ You will need the following dependencies (Ubuntu, Debian): # Compiling on Linux -1. Change into the out-of-tree build subdirectory of the source tree: +1. Clone source and dependencies - mkdir IMP/build; cd IMP/build + git clone https://... + cd IMP + git submodule init + git submodule update -2. Create the makefile via qmake: +2. Change into the out-of-tree build subdirectory of the source tree: + + mkdir build; cd build + +3. Create the makefile via qmake: qmake --qt=5 ../src/imp.pro -3. Build the binary: +4. Build the binary: make -4. For the easiest install, just run make install to automatically set up the shared data and desktop launcher. +5. For the easiest install, just run make install to automatically set up the shared data and desktop launcher. sudo make install diff --git a/data/dictionaries/dumbnames b/data/dictionaries/dumbnames new file mode 100644 index 0000000..0872646 --- /dev/null +++ b/data/dictionaries/dumbnames @@ -0,0 +1 @@ +R3 Clear diff --git a/docs/RELEASES b/docs/RELEASES index ec1bdfa..70e36e6 100644 --- a/docs/RELEASES +++ b/docs/RELEASES @@ -1,8 +1,21 @@ -0.9.3 - Fixed false KOS results when CVA checker has a partial name match +0.9.3 - New feature: Instead of one alert sound, you can now configure + differing sounds (or the same sound) at differing (or the same) + volumes for each jump away you wish to be alerted. If you've + previously configured alerts, IMP will set the proximity + configuration to give you the same results. New users get two + defaults (for zero and one jump) that they can amend. + + Fixed false KOS results when CVA checker has a partial name match or if a pilot's name matches an Alliance/Corp. Parser improvements for when people are saying a system is *not* - or are just saying a gate is clear. + clear or are just saying a gate is clear. + + No longer warns new users that rules file doesn't exist. Instead + it creates one default rule that plays a sound if someone says + things like " red" or "kos!" in local. + + Updated Linux build instructions to include submodules. 0.9.2 - Fixed parser bug where questions where not being marked as such. @@ -314,7 +327,17 @@ Coming soon: +- kos msg for red by last should show person and corp. - fix display of messages with backslashes. -- additional sound/volume options for alerts, dependant on jump distance. - better pilot cache/cleanup. - if at war, and going hisec, play a "bad idea" sound. +- theme customization for system images +- TTS support +- Maybe an option to auto-change region? +- Poll/repoll pilots option +- WH icon for system (xxx-xx contains/has a wh|wormhole|hole) +- Clear wh: (xxx-xx wh closed|collapsed|gone) +- Make mini militia faction count (RBL npc corps)? +- Add some intelligence to handle dumb names like R3 Clear +- Add option to autobuild jumpbridge list from dotlan instead of files. +- Break follow transistion mode on screen reposition. diff --git a/src/alarmmodel.cpp b/src/alarmmodel.cpp new file mode 100755 index 0000000..fcc80ec --- /dev/null +++ b/src/alarmmodel.cpp @@ -0,0 +1,240 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#include +#include "alarmmodel.h" + +AlarmModel::AlarmModel(QObject *parent) + : QAbstractTableModel(parent) +{ +} + +QVariant AlarmModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole) + { + if (orientation == Qt::Horizontal) { + switch (section) + { + case 0: + return QString("Jumps"); + case 1: + return QString("Alarm"); + case 2: + return QString("Volume"); + case 3: + return QString("Play"); + } + } + else + { + return section + 1; + } + } + return QVariant(); +} + +int AlarmModel::rowCount(const QModelIndex& /*&parent*/) const +{ + return alarms.count(); +} + +int AlarmModel::columnCount(const QModelIndex& /*&parent*/) const +{ + return 4; +} + +QVariant AlarmModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + switch(role) + { + case Qt::TextAlignmentRole: + switch(index.column()) + { + case 0: + return Qt::AlignRight; + default: + return Qt::AlignHCenter; + } + break; + + case Qt::DisplayRole: + case Qt::EditRole: + if (index.row() < alarms.count()) + { + switch (index.column()) + { + case 0: + return alarms[index.row()].jumps; + case 1: + return alarms[index.row()].file; + case 2: + return alarms[index.row()].volume; + default: + break; + } + } + break; + + case Qt::CheckStateRole: + if (index.row() < alarms.count()) + { + switch (index.column()) + { + default: + break; + } + } + break; + + case Qt::ToolTipRole: + switch (index.column()) + { + case 0: + return QString("Number of jumps away"); + case 1: + return QString("Sound file to play on alarm"); + case 2: + return QString("Volume level of the alarm"); + case 3: + return QString("Test the sound/volume"); + default: + break; + } + } + + return QVariant(); +} + +bool AlarmModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (role == Qt::EditRole) + { + switch (index.column()) + { + case 0: + alarms[index.row()].jumps = value.toInt(); + break; + case 1: + alarms[index.row()].file = value.toString(); + break; + case 2: + alarms[index.row()].volume = value.toFloat(); + break; + default: + break; + } + + emit dataChanged(index, index, QVector() << role); + return true; + } + + return false; +} + +Qt::ItemFlags AlarmModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + if (index.column() == 0 || index.column() == 3) + { + return Qt::ItemIsEnabled | QAbstractTableModel::flags(index); + } + else + { + return Qt::ItemIsEditable | QAbstractTableModel::flags(index); + } +} + +bool AlarmModel::insertRows(int row, int count, const QModelIndex &parent) +{ + if(row < 0) + row = alarms.count(); + + beginInsertRows(parent, row, row + count - 1); + + alarms.insert(row, Alarm{(uint)row, "red-alert.wav", 1.0}); + for(int i = 0; i < alarms.count(); i++) + { + alarms[i].jumps = i; + } + + endInsertRows(); + return true; +} + +bool AlarmModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if(row < 0) + row = alarms.count() - 1; + + beginRemoveRows(parent, row, row + count - 1); + if(row == 0 && count == alarms.count()) + { + alarms.clear(); + } + else + { + for(int i = 0; i < count; i++) + { + alarms.removeAt(row); + } + } + + for(int i = 0; i < alarms.count(); i++) + { + alarms[i].jumps = i; + } + + endRemoveRows(); + + return true; +} + +void AlarmModel::insertAlarm(QString filename, float volume) +{ + beginInsertRows(QModelIndex(), alarms.count(), alarms.count()); + + alarms.insert(alarms.count(), Alarm{(uint)alarms.count(), filename, volume}); + + endInsertRows(); +} + +QList AlarmModel::getAlarms() +{ + return alarms; +} + +void AlarmModel::setAlarms(QList newAlarms) +{ + if(newAlarms.count() <= 0) + return; + + beginRemoveRows(QModelIndex(), 0, alarms.count()-1); + alarms.clear(); + endRemoveRows(); + beginInsertRows(QModelIndex(), 0, newAlarms.count()-1); + alarms = newAlarms; + endInsertRows(); +} diff --git a/src/alarmmodel.h b/src/alarmmodel.h new file mode 100755 index 0000000..bcb8ee4 --- /dev/null +++ b/src/alarmmodel.h @@ -0,0 +1,76 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#ifndef ALARMMODEL_H +#define ALARMMODEL_H + +#include +#include + +struct Alarm +{ + uint jumps; + QString file; + float volume; +}; + +class AlarmModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit AlarmModel(QObject *parent = 0); + + const Alarm& at(int distance) {return alarms[distance];} + int count() {return alarms.count();} + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + // Editable: + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex& index) const override; + + // Add data: + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + // Remove data: + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + void insertAlarm(QString filename, float volume); + //void removeAlarm(const QModelIndexList indexList); + QList getAlarms(); + void setAlarms(QList newAlarms); + + QList alarmCombos; + +private: + QList alarms; +}; + +#endif // AlarmModel_H diff --git a/src/audio.cpp b/src/audio.cpp index dcc03b5..e34e58c 100755 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -64,10 +64,25 @@ void ImpAudio::playLocalFile(const QString& fileName) effects.insert(fileName, effect); } + effects[fileName]->setVolume(m_volume); + effects[fileName]->play(); +} + +void ImpAudio::playLocalFile(const QString& fileName, float volume) +{ + if(!effects.contains(fileName)) + { + QString path = appFilesPath() + "/audio/" + fileName; + QSoundEffect* effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(path)); + effects.insert(fileName, effect); + } + effects[fileName]->setVolume(volume); effects[fileName]->play(); } +/* QSoundEffect* ImpAudio::oldPlayLocalFile(const QString& fileName) { QString path = appFilesPath() + "/audio/" + fileName; @@ -86,7 +101,7 @@ QSoundEffect* ImpAudio::oldPlayLocalFile(const QString& fileName) qDebug() << "ImpAudio::playLocalFile - played " << &effect; return effect; } - +*/ void ImpAudio::playingChanged() { QSoundEffect *s = qobject_cast (sender()); @@ -106,8 +121,8 @@ void ImpAudio::setVolume(int i) QAudio::LogarithmicVolumeScale, QAudio::LinearVolumeScale); */ - volume = i / qreal(100.0); - qDebug() << "Volume changed to " << QString::number(volume, 'g', 2); + m_volume = i / qreal(100.0); + qDebug() << "Volume changed to " << QString::number(m_volume, 'g', 2); } void ImpAudio::playLocalMedia(const QString& fileName) diff --git a/src/audio.h b/src/audio.h index 593b971..83fb033 100755 --- a/src/audio.h +++ b/src/audio.h @@ -33,7 +33,9 @@ class ImpAudio : public QObject explicit ImpAudio(QObject *parent = 0); void playLocalFile(const QString& fileName); - QSoundEffect* oldPlayLocalFile(const QString& fileName); + void playLocalFile(const QString& fileName, float volume); + + //QSoundEffect* oldPlayLocalFile(const QString& fileName); void playLocalMedia(const QString& fileName); void stopMusic(); @@ -48,7 +50,7 @@ public slots: void playingChanged(); private: - qreal volume = 1.0f; + qreal m_volume = 1.0f; QMediaPlayer* player; QMap effects; diff --git a/src/chatitemdelegate.cpp b/src/chatitemdelegate.cpp index 9dccb51..e21e542 100644 --- a/src/chatitemdelegate.cpp +++ b/src/chatitemdelegate.cpp @@ -69,11 +69,6 @@ void ChatItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti } } -void ChatItemDelegate::setModel(ChatModel* model) -{ - m_model = model; -} - QTextDocument* ChatItemDelegate::document(const QStyleOptionViewItem &option) const { QStyleOptionViewItem options = option; diff --git a/src/chatitemdelegate.h b/src/chatitemdelegate.h index 16847a1..7d63597 100644 --- a/src/chatitemdelegate.h +++ b/src/chatitemdelegate.h @@ -37,7 +37,7 @@ class ChatItemDelegate : public QStyledItemDelegate void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const override; - void setModel(ChatModel* model); + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; QString anchorAt(const QStyleOptionViewItem &option, const QModelIndex &index, const QPoint &point); @@ -46,7 +46,6 @@ class ChatItemDelegate : public QStyledItemDelegate public slots: private: - ChatModel* m_model; QSize m_avatarSize = QSize(64,64); QSize padding = QSize(2,1); diff --git a/src/chatview.cpp b/src/chatview.cpp index 63cde95..4b79c1c 100644 --- a/src/chatview.cpp +++ b/src/chatview.cpp @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #include #include #include @@ -58,13 +78,11 @@ QString ChatView::anchorAt(const QPoint &pos) const { auto chatDelegate = qobject_cast(delegate); if (chatDelegate != 0) { - //-----jj QStyleOptionViewItem option; option.widget = this; option.text = model()->data(index, Qt::DisplayRole).toString(); option.icon = model()->data(index, Qt::DecorationRole).value(); - QRect itemRect = visualRect(index); QPoint relativeClickPosition = pos - itemRect.topLeft(); option.rect = itemRect; diff --git a/src/chatview.h b/src/chatview.h index 1581f17..67bef76 100644 --- a/src/chatview.h +++ b/src/chatview.h @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #ifndef CHATVIEW_H #define CHATVIEW_H diff --git a/src/combodelegate.cpp b/src/combodelegate.cpp new file mode 100644 index 0000000..ca717c7 --- /dev/null +++ b/src/combodelegate.cpp @@ -0,0 +1,75 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#include "combodelegate.h" + +#include +#include +#include +#include +#include + +ComboDelegate::ComboDelegate(QObject *parent) : QStyledItemDelegate(parent) +{ + +} + +QWidget* ComboDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem& /*option*/, + const QModelIndex& /*index*/) const +{ + QComboBox* editor = new QComboBox(parent); + editor->clear(); + foreach(QString item, comboItems) + { + editor->addItem(item); + } + return editor; +} + +void ComboDelegate::setItems(QStringList items) +{ + comboItems.clear(); + comboItems.append(items); +} + +// Gets the data from Model and feeds the data to delegate Editor +void ComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QString currentText = index.model()->data(index, Qt::EditRole).toString(); + + QComboBox *comboBox = static_cast(editor); + comboBox->setCurrentText(currentText); +} + + // When we modify data, this model reflect the change + // Data from the delegate to the model + void ComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const + { + QComboBox *comboBox = static_cast(editor); + QString text = comboBox->itemText(0); + model->setData(index, comboBox->currentText(), Qt::EditRole); + } + +// Give the info on size and location +void ComboDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & /*index*/) const +{ + editor->setGeometry(option.rect); +} diff --git a/src/combodelegate.h b/src/combodelegate.h new file mode 100644 index 0000000..620f5ce --- /dev/null +++ b/src/combodelegate.h @@ -0,0 +1,56 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#ifndef COMBODELEGATE_H +#define COMBODELEGATE_H + +#include +#include +#include + +class ComboDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit ComboDelegate(QObject *parent = Q_NULLPTR); + + void setItems(QStringList items); + +// void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; +// bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); + + // Create Editor when we construct MyDelegate + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + // Then, we set the Editor + void setEditorData(QWidget *editor, const QModelIndex &index) const; + + // When we modify data, this model reflect the change + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + + // Give the SpinBox the info on size and location + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + QStringList comboItems; +}; + +#endif // COMBODELEGATE_H diff --git a/src/graphics/volume-icon.png b/src/graphics/volume-icon.png index f8f504f..f4a280e 100755 Binary files a/src/graphics/volume-icon.png and b/src/graphics/volume-icon.png differ diff --git a/src/imp.pro b/src/imp.pro index 8c83cf7..28489c9 100644 --- a/src/imp.pro +++ b/src/imp.pro @@ -48,7 +48,11 @@ SOURCES += \ msgstyle.cpp \ utility.cpp \ chatview.cpp \ - themecustomizer.cpp + themecustomizer.cpp \ + alarmmodel.cpp \ + combodelegate.cpp \ + volumedelegate.cpp \ + playdelegate.cpp HEADERS += \ mainwindow.h \ @@ -76,7 +80,11 @@ HEADERS += \ msgstyle.h \ utility.h \ chatview.h \ - themecustomizer.h + themecustomizer.h \ + alarmmodel.h \ + combodelegate.h \ + volumedelegate.h \ + playdelegate.h FORMS += \ mainwindow.ui \ @@ -103,7 +111,9 @@ DISTFILES += \ ../docs/RULES \ ../docs/THEMES \ ../docs/CREDITS \ - ../docs/DICTIONARIES + ../docs/DICTIONARIES \ + ../INSTALL.md \ + ../data/dictionaries/dumbnames RESOURCES += \ resources.qrc diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d44753b..296e09c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -97,7 +97,6 @@ MainWindow::MainWindow(QWidget *parent) : chatModel->setPilotCache(&pilotCache); msgStyle = new MsgStyle(this); m_cid = new ChatItemDelegate(msgStyle, this); - m_cid->setModel(chatModel); loadSettings(); @@ -544,8 +543,8 @@ void MainWindow::gotRblReply(QString name, bool rbl, int corpNum) if(corpNum > 1) { - info.text = name + " is RED BY LAST!"; - info.markedUpText = name + " is RED BY LAST!"; + info.text = name + " RED BY LAST (" + name +")!"; + info.markedUpText = " RED BY LAST (" + name + ") !"; } else { @@ -1201,7 +1200,6 @@ void MainWindow::fileChanged(const QString &absoluteFilePath) ) / 1000; if(secondsDiff < 10) { - bool play = false; foreach(QString system, message.systems) { // Test each pilot location to see if it is near affected system @@ -1213,7 +1211,7 @@ void MainWindow::fileChanged(const QString &absoluteFilePath) QString pilotLoc = regionMap->pilotsSystem(pilot); if(regionMap->contains(pilotLoc) && - regionMap->distanceBetween(pilotLoc, system) <= options.getAlarmDistance() + options.withinAlarmDistance(regionMap->distanceBetween(pilotLoc, system)) ) { changeImpStatus("Setting " + system + " to red."); @@ -1230,7 +1228,9 @@ void MainWindow::fileChanged(const QString &absoluteFilePath) qDebug() << "-pilotLoc: " << pilotLoc << " system: " << system; lastAlertTime = QDateTime::currentDateTimeUtc(); lastAlertSystem = system; - play = true; + + Alarm alarm = options.getAlarmForDistance(regionMap->distanceBetween(pilotLoc, system)); + audio.playLocalFile(alarm.file, alarm.volume); } // If this is within alarm distance, let's update the map NOW. @@ -1239,10 +1239,6 @@ void MainWindow::fileChanged(const QString &absoluteFilePath) } } } - if (play) - { - audio.playLocalFile(options.getSoundAlarm()); - } } } toBeAddedToList = true; diff --git a/src/mapscene.cpp b/src/mapscene.cpp index 718efc5..72a6fa8 100644 --- a/src/mapscene.cpp +++ b/src/mapscene.cpp @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #include "mapscene.h" #include "systemshape.h" diff --git a/src/mapscene.h b/src/mapscene.h index 1abec41..41458d6 100644 --- a/src/mapscene.h +++ b/src/mapscene.h @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #ifndef MAPSCENE_H #define MAPSCENE_H diff --git a/src/msgstyle.cpp b/src/msgstyle.cpp index c1e62c1..53737de 100644 --- a/src/msgstyle.cpp +++ b/src/msgstyle.cpp @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #include "msgstyle.h" MsgStyle::MsgStyle(QWidget *parent) : QWidget(parent) diff --git a/src/msgstyle.h b/src/msgstyle.h index 9a0d9f2..dd92f73 100644 --- a/src/msgstyle.h +++ b/src/msgstyle.h @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #ifndef MSGSTYLE_H #define MSGSTYLE_H diff --git a/src/options.cpp b/src/options.cpp index c6d4723..1e09e57 100755 --- a/src/options.cpp +++ b/src/options.cpp @@ -21,6 +21,7 @@ #include "options.h" #include "ui_options.h" #include "abstract_os.h" +#include "combodelegate.h" #include #include @@ -38,16 +39,37 @@ Options::Options(QWidget *parent) : ui->setupUi(this); ui->intelEdit->installEventFilter(this); + comboDelegate = new ComboDelegate(this); + volumeDelegate = new VolumeDelegate(this); + playDelegate = new PlayDelegate(this); + connect(playDelegate, &PlayDelegate::playSound, + this, &Options::testSound); + rebuildAudioFileList(); rebuildStyleFileList(); + alarmModel = new AlarmModel(this); + ui->tableProxAlarms->setModel(alarmModel); + ui->tableProxAlarms->setEditTriggers(QAbstractItemView::AllEditTriggers); + ui->tableProxAlarms->verticalHeader()->hide(); + ui->tableProxAlarms->setItemDelegateForColumn(1, comboDelegate); + ui->tableProxAlarms->setItemDelegateForColumn(2, volumeDelegate); + ui->tableProxAlarms->setItemDelegateForColumn(3, playDelegate); + ui->tableProxAlarms->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); + ui->tableProxAlarms->setColumnWidth(0, 50); + ui->tableProxAlarms->setColumnWidth(2, 300); + ui->tableProxAlarms->setColumnWidth(3, 50); + //ui->tableProxAlarms->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); + //ui->tableProxAlarms->verticalHeader()->setDefaultSectionSize(48); + ui->tableProxAlarms->show(); + ruleModel = new RuleModel(this); ui->tableView->setModel(ruleModel); - ui->tableView->setColumnWidth(0, 25); + ui->tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch); + ui->tableView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch); + ui->tableView->setColumnWidth(0, 30); ui->tableView->setColumnWidth(1, 100); - ui->tableView->setColumnWidth(2, 100); - ui->tableView->setColumnWidth(3, 310); - ui->tableView->setColumnWidth(4, 25); + ui->tableView->setColumnWidth(4, 30); ui->tableView->show(); } @@ -58,7 +80,6 @@ Options::~Options() void Options::rebuildAudioFileList() { - ui->alarmCombo->clear(); ui->comboIncomplete->clear(); ui->clipKosCombo->clear(); ui->clipNotKosCombo->clear(); @@ -75,20 +96,22 @@ void Options::rebuildAudioFileList() if(fileInfo.fileName().endsWith(".dll")) continue; - ui->alarmCombo->addItem(fileInfo.fileName()); ui->comboIncomplete->addItem(fileInfo.fileName()); ui->clipKosCombo->addItem(fileInfo.fileName()); ui->clipNotKosCombo->addItem(fileInfo.fileName()); ui->statusCombo->addItem(fileInfo.fileName()); ui->essCombo->addItem(fileInfo.fileName()); + + m_soundList.append(fileInfo.fileName()); } - ui->alarmCombo->setCurrentIndex(ui->alarmCombo->findText(m_soundAlarm)); ui->statusCombo->setCurrentIndex(ui->statusCombo->findText(m_soundStatus)); ui->comboIncomplete->setCurrentIndex(ui->comboIncomplete->findText(m_soundIncomplete)); ui->clipKosCombo->setCurrentIndex(ui->clipKosCombo->findText(m_soundIsKos)); ui->clipNotKosCombo->setCurrentIndex(ui->clipNotKosCombo->findText(m_soundNoKos)); ui->essCombo->setCurrentIndex(ui->essCombo->findText(m_soundEss)); + + comboDelegate->setItems(m_soundList); } void Options::rebuildStyleFileList() @@ -121,8 +144,6 @@ void Options::cacheSettings() } _intelChannels = channels; - _alarmDistance = ui->distanceSpinBox->value(); - _volume = ui->volume->value(); _avatarExpiration = ui->avatarBox->value(); _historyCount = ui->historySpinBox->value(); _autoPeriod = ui->autoPeriodSpin->value(); @@ -141,7 +162,6 @@ void Options::cacheSettings() m_initOldIntel = ui->checkOldIntel->isChecked(); - m_soundAlarm = ui->alarmCombo->currentText(); m_soundStatus = ui->statusCombo->currentText(); m_soundIncomplete = ui->comboIncomplete->currentText(); m_soundIsKos = ui->clipKosCombo->currentText(); @@ -155,6 +175,7 @@ void Options::cacheSettings() _fontName = ui->fontComboBox->currentText(); _fontSize = ui->fontSpinBox->value(); + m_alarms = alarmModel->getAlarms(); _rules = ruleModel->getRules(); m_style = ui->comboStyle->currentText(); @@ -165,8 +186,6 @@ void Options::restoreSettings() ui->intelWidget->clear(); ui->intelWidget->addItems(_intelChannels); - ui->distanceSpinBox->setValue(_alarmDistance); - ui->volume->setValue(_volume); ui->avatarBox->setValue(_avatarExpiration); ui->historySpinBox->setValue(_historyCount); ui->autoPeriodSpin->setValue(_autoPeriod); @@ -184,7 +203,6 @@ void Options::restoreSettings() ui->checkAvatar->setChecked(m_showAvatar); ui->checkOldIntel->setChecked(m_initOldIntel); - ui->alarmCombo->setCurrentIndex(ui->alarmCombo->findText(m_soundAlarm)); ui->statusCombo->setCurrentIndex(ui->statusCombo->findText(m_soundStatus)); ui->comboIncomplete->setCurrentIndex(ui->comboIncomplete->findText(m_soundIncomplete)); ui->clipKosCombo->setCurrentIndex(ui->clipKosCombo->findText(m_soundIsKos)); @@ -206,6 +224,7 @@ void Options::restoreSettings() ui->fontComboBox->setCurrentIndex(ui->fontComboBox->findText(_fontName)); ui->fontSpinBox->setValue(_fontSize); + alarmModel->setAlarms(m_alarms); ruleModel->setRules(_rules); ui->comboStyle->setCurrentIndex(ui->comboStyle->findText(m_style)); @@ -228,7 +247,7 @@ void Options::loadSettings(QSettings& settings) m_disabledPilots = m_disabledPilots.fromList(dpList); ui->avatarBox->setValue(settings.value("avatarExpiration", 0).toInt()); - ui->distanceSpinBox->setValue(settings.value("alarmDistance", 1).toInt()); + ui->historySpinBox->setValue(settings.value("historyCount", 0).toInt()); ui->autoPeriodSpin->setValue(settings.value("autoPeriod", 4000).toInt()); ui->autoRefreshSpin->setValue(settings.value("autoRefresh", 33).toInt()); @@ -245,16 +264,14 @@ void Options::loadSettings(QSettings& settings) ui->checkAvatar->setChecked(settings.value("showAvatar", true).toBool()); ui->checkOldIntel->setChecked(settings.value("initOldIntel", true).toBool()); - ui->volume->setValue(settings.value("volume", 100).toInt()); - audio->setVolume(ui->volume->value()); + // Deprecated - remove after a few versions + _alarmDistance = settings.value("alarmDistance", 1).toInt(); + _volume = settings.value("volume", 100).toInt(); + audio->setVolume(_volume); + m_soundAlarm = settings.value("soundAlarm", "red-alert.wav").toString(); // On Linux, you can just setCurrentText(), but there appears to be a Qt bug on Windows // such that it doesn't update the index. - ui->alarmCombo->setCurrentIndex( - ui->alarmCombo->findText( - settings.value("soundAlarm", "red-alert.wav").toString() - ) - ); ui->essCombo->setCurrentIndex( ui->essCombo->findText( settings.value("soundEss", "sci-fi-alarm.wav").toString() @@ -290,12 +307,6 @@ void Options::loadSettings(QSettings& settings) // Hack that works around a problem where null values are written if the previous run // exited uncleanly. This can happen when the parser files aren't found, but // I'm just going to brute force fix this for now. - - if(ui->alarmCombo->currentText() == "") { - ui->alarmCombo->setCurrentIndex( - ui->alarmCombo->findText("red-alert.wav") - ); - } if(ui->essCombo->currentText() == "") { ui->essCombo->setCurrentIndex( ui->essCombo->findText("sci-fi-alarm.wav") @@ -372,14 +383,15 @@ void Options::loadSettings(QSettings& settings) ); ui->fontSpinBox->setValue(settings.value("fontSize", 10).toInt()); - // Load rules QString dataPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); QDir dataDir{dataPath}; - QFile file(dataDir.absoluteFilePath("imp_rules")); - if (file.open(QFile::ReadOnly | QFile::Text)) + // Load rules + QFile ruleFile(dataDir.absoluteFilePath("imp_rules")); + + if (ruleFile.open(QFile::ReadOnly | QFile::Text)) { - QXmlStreamReader reader(&file); + QXmlStreamReader reader(&ruleFile); while (!reader.atEnd() && !reader.hasError()) { @@ -395,21 +407,75 @@ void Options::loadSettings(QSettings& settings) } else { - QMessageBox::information(NULL, "IMP Rules not found", "An existing " - "IMP rule file was not found. This is normal " - "when running IMP for the first time. A rules " - "file will be created when the program exits.", - QMessageBox::Ok); + ruleModel->insertRule(true, "Lo[ck]al", " ([Rr][Ee][Dd]|[Kk][Oo][Ss])[\\.!]?$", "play system-grind-01.wav", true); } + // Load alarms + QFile alarmFile(dataDir.absoluteFilePath("imp_alarms")); + + if (alarmFile.open(QFile::ReadOnly | QFile::Text)) + { + QXmlStreamReader reader(&alarmFile); + + while (!reader.atEnd() && !reader.hasError()) + { + reader.readNext(); + if (reader.isStartElement()) + { + if (reader.name() == "Alarms") + { + alarmModel->setAlarms(readAlarms(reader)); + } + } + } + } + else + { + if(m_soundAlarm.length() > 0) + { + // Bring in legacy values, if they're in config. + for(int i=0; i <= _alarmDistance; i++) + { + alarmModel->insertAlarm(m_soundAlarm, _volume/100.0f); + } + } + else + { + // New Default + alarmModel->insertAlarm("red-alert.wav", 1.0f); + alarmModel->insertAlarm("Danger.wav", 1.0f); + } + } + + cacheSettings(); } +QList Options::readAlarms(QXmlStreamReader& reader) +{ + QList alarms; + + while (!reader.atEnd() && !reader.hasError()) + { + reader.readNext(); + if (reader.isStartElement()) + { + if (reader.name() == "Alarm") + { + Alarm alarm; + readAlarmTextElements(reader, alarm); + alarms.append(alarm); + } + } + } + + return alarms; +} + QList Options::readRules(QXmlStreamReader& reader) { QList rules; - while (!reader.atEnd() && !reader.hasError()) { reader.readNext(); @@ -431,7 +497,7 @@ QList Options::readRules(QXmlStreamReader& reader) } } - readTextElements(reader, rule); + readRuleTextElements(reader, rule); rules.append(rule); } } @@ -440,7 +506,31 @@ QList Options::readRules(QXmlStreamReader& reader) return rules; } -void Options::readTextElements(QXmlStreamReader& reader, Rule& rule) +void Options::readAlarmTextElements(QXmlStreamReader& reader, Alarm& rule) +{ + while (!reader.atEnd() && !reader.hasError()) + { + reader.readNext(); + if (reader.isStartElement()) + { + if (reader.name() == "Jumps") + { + rule.jumps = reader.readElementText().toInt(); + } + else if (reader.name() == "Sound") + { + rule.file = reader.readElementText(); + } + else if (reader.name() == "Volume") + { + rule.volume = reader.readElementText().toFloat(); + return; + } + } + } + +} +void Options::readRuleTextElements(QXmlStreamReader& reader, Rule& rule) { while (!reader.atEnd() && !reader.hasError()) { @@ -463,6 +553,7 @@ void Options::readTextElements(QXmlStreamReader& reader, Rule& rule) } } } + void Options::saveSettings() //QSettings& settings) { QString configPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); @@ -479,10 +570,8 @@ void Options::saveSettings() //QSettings& settings) settings.setValue("intelChannels", getIntelChannels()); settings.setValue("avatarExpiration", getAvatarExpiration()); - settings.setValue("alarmDistance", getAlarmDistance()); settings.setValue("themeName", getThemeName()); settings.setValue("themeType", getThemeType()); - settings.setValue("volume", getAlarmVolume()); settings.setValue("historyCount", getHistoryMax()); settings.setValue("autoPeriod", getAutoPeriod()); settings.setValue("autoRefresh", getAutoRefresh()); @@ -499,7 +588,7 @@ void Options::saveSettings() //QSettings& settings) settings.setValue("smoothAutofollow", getSmoothAutofollow()); settings.setValue("essAndKos", getEssAndKos()); - settings.setValue("soundAlarm", getSoundAlarm()); + //settings.setValue("soundAlarm", getSoundAlarm()); settings.setValue("soundStatus", getSoundStatus()); settings.setValue("soundIncomplete", getSoundIncompleteKos()); settings.setValue("soundIsKos", getSoundIsKos()); @@ -516,18 +605,19 @@ void Options::saveSettings() //QSettings& settings) settings.setValue("style", getStyle()); - // Save rules QString dataPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); QDir dataDir{dataPath}; - QFile file(dataDir.absoluteFilePath("imp_rules")); - if (!file.open(QFile::WriteOnly | QFile::Text)) { + // Save rules + QFile ruleFile(dataDir.absoluteFilePath("imp_rules")); + + if (!ruleFile.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(NULL, "Error Opening File", "Could not open output file " + - file.fileName() + ".", QMessageBox::Ok); + ruleFile.fileName() + ".", QMessageBox::Ok); return; } - QXmlStreamWriter xmlWriter(&file); + QXmlStreamWriter xmlWriter(&ruleFile); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement("Rules"); @@ -543,9 +633,34 @@ void Options::saveSettings() //QSettings& settings) xmlWriter.writeTextElement("Action", rules[i].action); xmlWriter.writeEndElement(); } - xmlWriter.writeEndDocument(); - file.close(); + ruleFile.close(); + + // Save alarms + QFile alarmFile(dataDir.absoluteFilePath("imp_alarms")); + + if (!alarmFile.open(QFile::WriteOnly | QFile::Text)) { + QMessageBox::warning(NULL, "Error Opening File", "Could not open output file " + + alarmFile.fileName() + ".", QMessageBox::Ok); + return; + } + + QXmlStreamWriter alarmXmlWriter(&alarmFile); + alarmXmlWriter.setAutoFormatting(true); + alarmXmlWriter.writeStartDocument(); + alarmXmlWriter.writeStartElement("Alarms"); + + QList alarms = alarmModel->getAlarms(); + for (int i = 0; i < alarms.count(); ++i) + { + alarmXmlWriter.writeStartElement("Alarm"); + alarmXmlWriter.writeTextElement("Jumps", QString::number(alarms[i].jumps)); + alarmXmlWriter.writeTextElement("Sound", alarms[i].file); + alarmXmlWriter.writeTextElement("Volume", QString::number(alarms[i].volume)); + alarmXmlWriter.writeEndElement(); + } + alarmXmlWriter.writeEndDocument(); + alarmFile.close(); } } @@ -559,11 +674,6 @@ int Options::getAvatarExpiration() return ui->avatarBox->value(); } -int Options::getAlarmDistance() -{ - return ui->distanceSpinBox->value(); -} - bool Options::getCheckForUpdate() { return ui->checkUpdates->isChecked(); @@ -579,11 +689,6 @@ int Options::getHistoryMax() return ui->historySpinBox->value(); } -int Options::getAlarmVolume() -{ - return ui->volume->value(); -} - bool Options::getAutofollow() { return _autofollow; @@ -671,11 +776,6 @@ bool Options::getSmoothAutofollow() return ui->smoothCheck->isChecked(); } -QString Options::getSoundAlarm() -{ - return ui->alarmCombo->currentText(); -} - QString Options::getSoundEss() { return ui->essCombo->currentText(); @@ -716,11 +816,6 @@ QString Options::getSoundStatus() return ui->statusCombo->currentText(); } -void Options::on_alarmTestButton_clicked() -{ - audio->playLocalFile(getSoundAlarm()); -} - void Options::on_buttonBox_accepted() { // If the log path was changed, let the main program know @@ -774,11 +869,6 @@ void Options::on_statusTestButton_clicked() audio->playLocalFile(getSoundStatus()); } -void Options::on_volume_sliderReleased() -{ - audio->setVolume(ui->volume->value()); -} - void Options::on_clipKosTestButton_clicked() { audio->playLocalFile(getSoundIsKos()); @@ -796,12 +886,18 @@ void Options::on_incompleteTestButton_clicked() void Options::on_ruleInsertButton_clicked() { - ruleModel->insertRule(ui->tableView->selectionModel()->selectedIndexes()); + //ruleModel->insertRule(ui->tableView->selectionModel()->selectedIndexes()); + QModelIndexList list = ui->tableProxAlarms->selectionModel()->selectedIndexes(); + int i = list.count() < 1 ? -1 : list[0].row(); + ruleModel->insertRow(i); } void Options::on_ruleRemoveButton_clicked() { - ruleModel->removeRule(ui->tableView->selectionModel()->selectedIndexes()); + //ruleModel->removeRule(ui->tableView->selectionModel()->selectedIndexes()); + QModelIndexList list = ui->tableProxAlarms->selectionModel()->selectedIndexes(); + int i = list.count() < 1 ? -1 : list[0].row(); + ruleModel->removeRow(i); } void Options::on_essTestButton_clicked() @@ -933,3 +1029,33 @@ void Options::on_buttonCheck_clicked() { emit checkForUpdate(); } + +void Options::on_btnInsertProx_clicked() +{ + QModelIndexList list = ui->tableProxAlarms->selectionModel()->selectedIndexes(); + int i = list.count() < 1 ? -1 : list[0].row(); + alarmModel->insertRow(i); +} + +void Options::on_btnRemoveProx_clicked() +{ + QModelIndexList list = ui->tableProxAlarms->selectionModel()->selectedIndexes(); + int i = list.count() < 1 ? -1 : list[0].row(); + alarmModel->removeRow(i); +} + +void Options::testSound(const QString& soundFileName, float volume) +{ + audio->playLocalFile(soundFileName, volume); +} + +bool Options::withinAlarmDistance(int distance) +{ + qDebug() << "Options::withinAlarmDistance : " << alarmModel->count() << " / " << distance; + return alarmModel->count() > distance; +} + +const Alarm& Options::getAlarmForDistance(int distance) +{ + return alarmModel->at(distance); +} diff --git a/src/options.h b/src/options.h index c717682..69f6723 100755 --- a/src/options.h +++ b/src/options.h @@ -21,9 +21,13 @@ #ifndef OPTIONS_H #define OPTIONS_H +#include "alarmmodel.h" #include "audio.h" +#include "combodelegate.h" +#include "playdelegate.h" #include "rulemodel.h" #include "theme.h" +#include "volumedelegate.h" #include #include @@ -51,9 +55,6 @@ class Options : public QDialog void setAudio(ImpAudio* impAudio); - int getAlarmDistance(); - int getAlarmVolume(); - bool getAutofollow(); void setAutofollow(bool checked); int getAutoPeriod(); @@ -100,7 +101,6 @@ class Options : public QDialog bool getSelfSuppress(); bool getSmoothAutofollow(); - QString getSoundAlarm(); QString getSoundEss(); QString getSoundStatus(); QString getSoundIncompleteKos(); @@ -122,6 +122,10 @@ class Options : public QDialog void setTheme(const QString& n, ThemeType t){ m_themeName = n; m_themeType = t; } + bool withinAlarmDistance(int distance); + const Alarm& getAlarmForDistance(int distance); + + AlarmModel* alarmModel; RuleModel* ruleModel; signals: @@ -138,11 +142,10 @@ class Options : public QDialog bool eventFilter(QObject *, QEvent *evt); private slots: + void testSound(const QString& soundFileName, float volume); void on_buttonBox_accepted(); void on_buttonBox_rejected(); - void on_alarmTestButton_clicked(); void on_statusTestButton_clicked(); - void on_volume_sliderReleased(); void on_clipKosTestButton_clicked(); void on_clipNotKosTestButton_clicked(); void on_ruleInsertButton_clicked(); @@ -155,16 +158,23 @@ private slots: void on_intelWidget_itemClicked(QListWidgetItem *item); void on_bridgeEdit_editingFinished(); void on_incompleteTestButton_clicked(); - void on_buttonCheck_clicked(); + void on_btnInsertProx_clicked(); + void on_btnRemoveProx_clicked(); private: Ui::Options *ui; + ComboDelegate* comboDelegate; + PlayDelegate* playDelegate; + VolumeDelegate* volumeDelegate; ImpAudio* audio; QString audioPath; - void readTextElements(QXmlStreamReader& reader, Rule& rule); + void readAlarmTextElements(QXmlStreamReader& reader, Alarm& rule); + QList readAlarms(QXmlStreamReader& reader); + + void readRuleTextElements(QXmlStreamReader& reader, Rule& rule); QList readRules(QXmlStreamReader& reader); bool _autofollow = true; @@ -203,14 +213,15 @@ private slots: QSet m_disabledPilots; QList _rules; + QList m_alarms; - QString m_soundAlarm; + QStringList m_soundList; + QString m_soundAlarm = ""; QString m_soundEss; QString m_soundIncomplete; QString m_soundIsKos; QString m_soundNoKos; QString m_soundStatus; - }; #endif // OPTIONS_H diff --git a/src/options.ui b/src/options.ui index 88d3593..3a2a32c 100755 --- a/src/options.ui +++ b/src/options.ui @@ -6,8 +6,8 @@ 0 0 - 675 - 438 + 1104 + 571 @@ -29,7 +29,7 @@ - + 0 @@ -40,82 +40,50 @@ QTabWidget::Rounded - 7 + 0 - + - Alerts + Proximity - - - - - - 0 - 0 - - - - Alarm Distance: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - + + + - + 0 0 - - 1 + + Sounds that are played when enemies are reported at varying distances. - - - - 0 - 0 - - + - Alarm: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Remove Selected - - - - 1 - 0 - - - - - - + - ... - - - - :/graphics/volume-icon.png:/graphics/volume-icon.png + Insert Alert - - - + + + + + Alerts + + + + + @@ -124,11 +92,11 @@ - Suppress redundant if within + Suppress alarms redundant if within - + @@ -144,10 +112,10 @@ - + - + 2 0 @@ -159,10 +127,10 @@ - + - + 0 0 @@ -175,7 +143,7 @@ - + Qt::Vertical @@ -188,7 +156,7 @@ - + @@ -204,7 +172,7 @@ - + @@ -214,7 +182,7 @@ - + ... @@ -225,7 +193,7 @@ - + @@ -241,7 +209,7 @@ - + @@ -251,7 +219,7 @@ - + ... @@ -262,7 +230,7 @@ - + Only alert on ESS when person is KOS. @@ -272,7 +240,7 @@ - + Volume: @@ -282,7 +250,7 @@ - + 100 @@ -297,6 +265,40 @@ + + + Rules + + + + + + + 0 + 0 + + + + Rules to take action when expressions are seen in channels. + + + + + + + Remove Rule + + + + + + + Insert Rule + + + + + KOS Checking @@ -538,7 +540,7 @@ 10000 - 3000 + 1000 @@ -1173,37 +1175,6 @@ - - - Rules - - - - - - - 0 - 0 - - - - - - - - Remove Rule - - - - - - - Insert Rule - - - - - User Interface @@ -1272,8 +1243,6 @@ - alarmCombo - alarmTestButton statusCombo statusTestButton essCombo diff --git a/src/parser.cpp b/src/parser.cpp index 8b72e3e..836f8bd 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -263,7 +263,7 @@ QList Parser::parseLine(const QString& line) } impWord.raw = text.mid(currentPos, nextSpace-currentPos); - qDebug() << "Parser::identifyObjects - raw =" << impWord.raw; + //qDebug() << "Parser::identifyObjects - raw =" << impWord.raw; if (puncPostExp.indexIn(impWord.raw) != -1) impWord.postfix = puncPostExp.cap(); @@ -281,15 +281,15 @@ QList Parser::parseLine(const QString& line) } impWord.prefixStart = currentPos; - qDebug() << "Parser::identifyObjects - prefix =" << impWord.prefix << + /*qDebug() << "Parser::identifyObjects - prefix =" << impWord.prefix << ", prefixStart =" << impWord.prefixStart << ", postfix =" << impWord.postfix << ", postfixStart =" << impWord.postfixStart; - +*/ impWord.actual = impWord.raw.mid(impWord.prefix.length(), impWord.raw.length()-impWord.postfix.length()); - qDebug() << "Parser::identifyObjects - actual =" << impWord.actual; + //qDebug() << "Parser::identifyObjects - actual =" << impWord.actual; currentPos = nextSpace + 1; impSentence->append(impWord); @@ -312,10 +312,10 @@ QList Parser::parseLine(const QString& line) QString markedUpText = ""; foreach(QList s, impSentences) { - qDebug() << "impSentence:"; + /*qDebug() << "impSentence:"; foreach (ImpWord iw, s) { qDebug() << '\t' << iw.prefix << iw.actual << iw.postfix; - } + }*/ MessageInfo messageInfo; messageInfo.originalLine = line; @@ -358,7 +358,7 @@ QString Parser::identifyObjects(MessageInfo& messageInfo, QList &senten QStringList theseGates; // New parsing - qDebug() << "Parser::identifyObjects - Parsing sentence in: " << messageInfo.text; + //qDebug() << "Parser::identifyObjects - Parsing sentence in: " << messageInfo.text; for(int i=0; i &senten // Fall out and let normal processing light up the system. handled = false; } - else if(sentence[i-1].actual.toLower() != "gate") + else if(sentence[i-1].actual.toLower() == "gate") { // We don't want to clear a system if someone says a gate is clear // "> KBP Dital gate clr!" diff --git a/src/playdelegate.cpp b/src/playdelegate.cpp new file mode 100644 index 0000000..57c7820 --- /dev/null +++ b/src/playdelegate.cpp @@ -0,0 +1,60 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#include "playdelegate.h" + +#include +#include + +PlayDelegate::PlayDelegate(QObject *parent) : QStyledItemDelegate(parent) +{ + +} + +void PlayDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &/*index*/) const + { + QStyleOptionButton button; + button.rect = option.rect; + button.icon = QIcon(":/graphics/volume-icon.png"); + //button.text = "=^.^="; + button.state = QStyle::State_Enabled; + QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter); + } + + bool PlayDelegate::editorEvent(QEvent *event, + QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) + { + if( event->type() == QEvent::MouseButtonRelease ) + { + QMouseEvent * e = (QMouseEvent *)event; + if (option.rect.contains(e->x(),e->y())) + { + emit playSound(model->index(index.row(), 1).data(Qt::DisplayRole).toString(), + model->index(index.row(), 2).data(Qt::DisplayRole).toFloat()); + return true; + } + } + + return false; + } diff --git a/src/playdelegate.h b/src/playdelegate.h new file mode 100644 index 0000000..3728b09 --- /dev/null +++ b/src/playdelegate.h @@ -0,0 +1,47 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#ifndef PLAYDELEGATE_H +#define PLAYDELEGATE_H + +#include +#include + +class PlayDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + PlayDelegate(QObject *parent); + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + bool editorEvent(QEvent *event, + QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index); + +signals: + void playSound(const QString& soundFile, float volume); +}; + +#endif // PLAYDELEGATE_H diff --git a/src/rulemodel.cpp b/src/rulemodel.cpp index 8b5b82a..23fc97e 100755 --- a/src/rulemodel.cpp +++ b/src/rulemodel.cpp @@ -33,7 +33,7 @@ QVariant RuleModel::headerData(int section, Qt::Orientation orientation, int rol switch (section) { case 0: - return QString(""); + return QString("E"); case 1: return QString("Channel"); case 2: @@ -41,7 +41,7 @@ QVariant RuleModel::headerData(int section, Qt::Orientation orientation, int rol case 3: return QString("Action"); case 4: - return QString(""); + return QString("C"); } } else @@ -182,6 +182,9 @@ Qt::ItemFlags RuleModel::flags(const QModelIndex &index) const bool RuleModel::insertRows(int row, int count, const QModelIndex &parent) { + if(row < 0) + row = rules.count(); + beginInsertRows(parent, row, row + count - 1); rules.insert(row, Rule{false, "", "", "", true}); endInsertRows(); @@ -191,8 +194,10 @@ bool RuleModel::insertRows(int row, int count, const QModelIndex &parent) bool RuleModel::removeRows(int row, int count, const QModelIndex &parent) { + if(row < 0) + row = rules.count() - 1; + beginRemoveRows(parent, row, row + count - 1); - //rules.removeAt(row); if(row == 0 && count == rules.count()) { rules.clear(); @@ -209,18 +214,18 @@ bool RuleModel::removeRows(int row, int count, const QModelIndex &parent) return true; } -void RuleModel::insertRule(const QModelIndexList indexList) +void RuleModel::insertRule(bool enabled, + QString channel, + QString match, + QString action, + bool cont) { - int row = indexList.count() > 0 ? - indexList[0].row() : rules.count(); - insertRows(row, 1, QModelIndex()); -} + beginInsertRows(QModelIndex(), rules.count(), rules.count()); -void RuleModel::removeRule(const QModelIndexList indexList) -{ - int row = indexList.count() > 0 ? - indexList[0].row() : rules.count() - 1; - removeRows(row, 1, QModelIndex()); + rules.insert(rules.count(), + Rule{enabled, channel, match, action, cont}); + + endInsertRows(); } QList RuleModel::getRules() diff --git a/src/rulemodel.h b/src/rulemodel.h index cd957fe..4d5bc20 100755 --- a/src/rulemodel.h +++ b/src/rulemodel.h @@ -60,8 +60,12 @@ class RuleModel : public QAbstractTableModel // Remove data: bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - void insertRule(const QModelIndexList indexList); - void removeRule(const QModelIndexList indexList); + void insertRule(bool enabled, + QString channel, + QString match, + QString action, + bool cont); + QList getRules(); void setRules(QList rules); diff --git a/src/systemshape.cpp b/src/systemshape.cpp index c138ac0..154225e 100644 --- a/src/systemshape.cpp +++ b/src/systemshape.cpp @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #include "systemshape.h" #include diff --git a/src/systemshape.h b/src/systemshape.h index ad803d0..62ec1cd 100644 --- a/src/systemshape.h +++ b/src/systemshape.h @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #ifndef SYSTEMSHAPE_H #define SYSTEMSHAPE_H diff --git a/src/themecustomizer.cpp b/src/themecustomizer.cpp index 7ec059e..94eff62 100644 --- a/src/themecustomizer.cpp +++ b/src/themecustomizer.cpp @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #include "themecustomizer.h" #include "ui_themecustomizer.h" diff --git a/src/themecustomizer.h b/src/themecustomizer.h index 9b6fb0b..04aa5a6 100644 --- a/src/themecustomizer.h +++ b/src/themecustomizer.h @@ -1,3 +1,23 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + #ifndef THEMECUSTOMIZER_H #define THEMECUSTOMIZER_H diff --git a/src/volumedelegate.cpp b/src/volumedelegate.cpp new file mode 100644 index 0000000..7a8f9d9 --- /dev/null +++ b/src/volumedelegate.cpp @@ -0,0 +1,108 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#include "volumedelegate.h" + +//#include +#include +#include +#include +#include + +VolumeDelegate::VolumeDelegate(QObject *parent) : QStyledItemDelegate(parent) +{ + +} + +QWidget* VolumeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QSlider* editor = new QSlider(parent); + editor->setOrientation(Qt::Orientation::Horizontal); + editor->setGeometry(option.rect); + //editor->setAutoFillBackground(true); + + editor->setMinimum(0); + editor->setMaximum(100); + editor->setValue(index.data().toFloat() * 100); + + return editor; +} + +void VolumeDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QSlider slider; + //slider.setAutoFillBackground(false); + slider.setOrientation(Qt::Orientation::Horizontal); + slider.setMinimum(0); + slider.setMaximum(100); + + slider.setValue(index.model()->data(index, Qt::DisplayRole).toFloat() * 100); + slider.setGeometry(option.rect); + + QRect ourRect = option.rect; + + ourRect.setTopLeft(ourRect.topLeft() - painter->clipBoundingRect().topLeft().toPoint()); + slider.render(painter, ourRect.topLeft()); + + /* + QStyleOptionSlider sliderOption; + sliderOption.rect = option.rect; + sliderOption.state = option.state | QStyle::State_Enabled; + QApplication::style()->drawComplexControl(QStyle::CC_Slider, &sliderOption, painter, &slider); + */ +} + +void VolumeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + int value = (index.model()->data(index, Qt::EditRole).toFloat() * 100); + + QSlider* slider = static_cast(editor); + slider->setValue(value); +} + +void VolumeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + QSlider* slider = static_cast(editor); + float value = (slider->value()/100.0); + + model->setData(index, value, Qt::EditRole); +} + +QSize VolumeDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &/*index*/) const +{ + return QSize(option.rect.width(), option.rect.height()); +} + +void VolumeDelegate::commitAndCloseEditor() +{ + +} + +void VolumeDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &/* index */) const +{ + editor->setGeometry(option.rect); +} diff --git a/src/volumedelegate.h b/src/volumedelegate.h new file mode 100644 index 0000000..1b1b995 --- /dev/null +++ b/src/volumedelegate.h @@ -0,0 +1,60 @@ +/* + * Imp: Copyright 2016, 2017 Jesse Litton (imp@eternaldusk.com) + * + * This file is part of Imp. + * + * Imp 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. + * + * Imp 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 Imp. If not, see . + * + */ + +#ifndef VOLUMEDELEGATE_H +#define VOLUMEDELEGATE_H + +#include +#include + +class VolumeDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + VolumeDelegate(QObject *parent); + + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void setEditorData(QWidget *editor, + const QModelIndex &index) const; + + void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const; + + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + +private slots: + void commitAndCloseEditor(); +}; + +#endif // VOLUMEDELEGATE_H