abcc147ea14992e258cbace54b973dd2933866a7
[timedsilencer] / switchingeventlist.cpp
1 /*
2  * This file is part of TimedSilencer.
3  *
4  *  TimedSilencer is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  TimedSilencer is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with TimedSilencer.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <QStandardItemModel>
19 #include <QHeaderView>
20 #include <QSettings>
21 #include <QHash>
22 #include "profileevent.h"
23 #include "switchingeventlist.h"
24 #include "newalarmdlg.h"
25 #include "eventlistdelegate.h"
26 #include "alarmd_backend.h"
27
28 SwitchingEventList::SwitchingEventList(QWidget *parent) :
29     QTableView(parent)
30 {
31   setSelectionBehavior(QAbstractItemView::SelectRows);
32   model = new QStandardItemModel(0, 5);
33   // Set Header
34   model->setHeaderData(EV_STATUS, Qt::Horizontal, tr("Status"));
35   model->setHeaderData(EV_FROM, Qt::Horizontal, tr("From"));
36   model->setHeaderData(EV_TO, Qt::Horizontal, tr("To"));
37   model->setHeaderData(EV_REPEAT, Qt::Horizontal, tr("Repeat"));
38   setModel(model);
39   setItemDelegate(new EventListDelegate);
40   connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(editEvent(QModelIndex)));
41   // Hide vertical header
42   verticalHeader()->setVisible(false);
43   horizontalHeader()->setStretchLastSection(true);
44   hideColumn(EV_ID);
45   // Load saved events
46   loadSavedEvents();
47 }
48
49 SwitchingEventList::~SwitchingEventList() {
50   delete model;
51 }
52
53 void SwitchingEventList::updateRow(int row, ProfileEvent *pe) {
54   model->setData(model->index(row, EV_STATUS), pe->activated);
55   model->setData(model->index(row, EV_FROM), pe->from_time.toString());
56   model->setData(model->index(row, EV_TO), pe->to_time.toString());
57   model->setData(model->index(row, EV_REPEAT), ProfileEvent::formatDays(pe->days));
58   model->setData(model->index(row, EV_ID), pe->getID());
59 }
60
61 void SwitchingEventList::editEvent(QModelIndex index) {
62   if(!index.isValid()) return;
63   QByteArray edited_id = model->data(model->index(index.row(), EV_ID)).toByteArray();
64   if(index.column() == EV_STATUS) {
65     // Toggle activated state
66     const bool new_status = !index.data().toBool();
67     model->setData(index, new_status);
68     // Alter Alarmd events
69     if(new_status) {
70       // Was activated
71       AlarmdBackend::setProfileEvents(edited_id);
72     } else {
73       // Was deactivated
74       AlarmdBackend::deleteEvents(edited_id);
75     }
76   } else {
77     NewAlarmDlg dlg(this, edited_id);
78     connect(&dlg, SIGNAL(editedEvent(QByteArray,bool)), this, SLOT(editEvent(QByteArray,bool)));
79     connect(&dlg, SIGNAL(deletedEvent(QByteArray)), this, SLOT(deleteEvent(QByteArray)));
80     connect(&dlg, SIGNAL(newEvent(QVariant)), this, SLOT(addNewEvent(QVariant)));
81     dlg.exec();
82   }
83 }
84
85 void SwitchingEventList::loadSavedEvents() {
86   qDebug("Loading saved events");
87   QSettings settings("TimedSilencer", "TimedSilencer");
88   QHash<QString, QVariant> events = settings.value("events").toHash();
89   // Check for < v0.6 settings
90   if(!settings.value("from_time", QTime()).toTime().isNull()) {
91     qDebug("Old settings from < v0.6 were detected, importing...");
92     ProfileEvent pe;
93     pe.activated = settings.value("enabled", false).toBool();
94     pe.from_time = settings.value("from_time").toTime();
95     pe.to_time = settings.value("to_time").toTime();
96     pe.days << EVERY_DAY;
97     // Cookies
98     long from_cookie = settings.value("silencing_cookie", 0).toLongLong();
99     if(from_cookie > 0)
100       pe.alarmd_cookies << from_cookie;
101     long to_cookie = settings.value("unsilencing_cookie", 0).toLongLong();
102     if(to_cookie > 0)
103       pe.alarmd_cookies << to_cookie;
104     if(to_cookie == 0 || from_cookie == 0)
105       pe.activated = 0;
106     events.insert(pe.getID(), pe.save());
107     // Remove old format values
108     settings.clear();
109     // Save in new format
110     settings.setValue("events", events);
111   }
112   // Load >= v0.6 settings
113   bool settings_change = false;
114   foreach(QVariant e, events.values()) {
115     ProfileEvent *pe = ProfileEvent::load(e);
116     // Check if still active
117     if(pe->activated && !AlarmdBackend::checkIfStillActive(pe)) {
118       qDebug("An existing profile switching event is no longer active, updating its status");
119       pe->activated = false;
120       events[pe->getID()] = pe->save();
121       settings_change = true;
122     }
123     // Add new model row
124     const int nb_rows = model->rowCount();
125     model->setRowCount(nb_rows+1);
126     updateRow(nb_rows, pe);
127     // Clean up
128     delete pe;
129   }
130   if(settings_change)
131     settings.setValue("events", events);
132 }
133
134 void SwitchingEventList::addNewEvent(QVariant var_event) {
135   qDebug("Adding a new event to the list");
136   ProfileEvent *pe = ProfileEvent::load(var_event);
137   // Add new model row
138   const int nb_rows = model->rowCount();
139   model->setRowCount(nb_rows+1);
140   updateRow(nb_rows, pe);
141   delete pe;
142 }
143
144 void SwitchingEventList::editEvent(QByteArray id, bool new_status) {
145   const int row = getRowFromID(id);
146   qDebug("Editing event at row %d", row);
147   Q_ASSERT(row >= 0);
148   model->setData(model->index(row, EV_STATUS), new_status);
149 }
150
151 void SwitchingEventList::deleteEvent(QByteArray id) {
152   const int row = getRowFromID(id);
153   qDebug("Deleting an event (row: %d)", row);
154   Q_ASSERT(row >= 0);
155   model->removeRow(row);
156 }
157
158 int SwitchingEventList::getRowFromID(QByteArray id) {
159   for(int i=0; i<model->rowCount(); ++i) {
160     if(model->data(model->index(i, EV_ID)).toByteArray() == id)
161       return i;
162   }
163   return -1;
164 }