Added spanish translation
[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 const int ROW_HEIGHT = 60;
29
30 SwitchingEventList::SwitchingEventList(QWidget *parent) :
31     QTableView(parent)
32 {
33   setSelectionBehavior(QAbstractItemView::SelectRows);
34   model = new QStandardItemModel(0, 5);
35   // Set Header
36   model->setHeaderData(EV_STATUS, Qt::Horizontal, tr("Status"));
37   model->setHeaderData(EV_FROM, Qt::Horizontal, tr("From"));
38   model->setHeaderData(EV_TO, Qt::Horizontal, tr("To"));
39   model->setHeaderData(EV_REPEAT, Qt::Horizontal, tr("Repeat"));
40   setModel(model);
41   setItemDelegate(new EventListDelegate);
42   connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(editEvent(QModelIndex)));
43   // Hide vertical header
44   verticalHeader()->setVisible(false);
45   horizontalHeader()->setStretchLastSection(true);
46   hideColumn(EV_ID);
47   // Load saved events
48   loadSavedEvents();
49   // Height hint
50   if(verticalHeader()->defaultSectionSize() < ROW_HEIGHT)
51     verticalHeader()->setDefaultSectionSize(ROW_HEIGHT);
52   if (sizeHintForRow(0)>0)
53     setMinimumHeight(sizeHintForRow(0) * 5);
54 }
55
56 SwitchingEventList::~SwitchingEventList() {
57   delete model;
58 }
59
60 void SwitchingEventList::updateRow(int row, ProfileEvent *pe) {
61   model->setData(model->index(row, EV_STATUS), pe->activated, Qt::UserRole);
62   model->setData(model->index(row, EV_FROM), pe->from_time.toString("HH:mm"));
63   model->setData(model->index(row, EV_TO), pe->to_time.toString("HH:mm"));
64   model->setData(model->index(row, EV_REPEAT), ProfileEvent::formatDays(pe->days));
65   model->setData(model->index(row, EV_ID), pe->getID());
66 }
67
68 void SwitchingEventList::editEvent(QModelIndex index) {
69   if(!index.isValid()) return;
70   QByteArray edited_id = model->data(model->index(index.row(), EV_ID)).toByteArray();
71   if(index.column() == EV_STATUS) {
72     // Toggle activated state
73     const bool new_status = !index.data(Qt::UserRole).toBool();
74     model->setData(index, new_status, Qt::UserRole);
75     ProfileEvent::setStatus(edited_id, new_status);
76     // Alter Alarmd events
77     if(new_status) {
78       // Was activated
79       AlarmdBackend::setProfileEvents(edited_id);
80     } else {
81       // Was deactivated
82       AlarmdBackend::deleteEvents(edited_id);
83     }
84   } else {
85     NewAlarmDlg dlg(this, edited_id);
86     connect(&dlg, SIGNAL(editedEvent(QByteArray,bool)), this, SLOT(editEvent(QByteArray,bool)));
87     connect(&dlg, SIGNAL(deletedEvent(QByteArray)), this, SLOT(deleteEvent(QByteArray)));
88     connect(&dlg, SIGNAL(newEvent(QVariant)), this, SLOT(addNewEvent(QVariant)));
89     dlg.exec();
90   }
91 }
92
93 void SwitchingEventList::loadSavedEvents() {
94   qDebug("Loading saved events");
95   QSettings settings("TimedSilencer", "TimedSilencer");
96   QList<long> known_cookies;
97   QHash<QString, QVariant> events = settings.value("events").toHash();
98   // Check for < v0.6 settings
99   if(!settings.value("from_time", QTime()).toTime().isNull()) {
100     qDebug("Old settings from < v0.6 were detected, importing...");
101     ProfileEvent pe;
102     pe.activated = settings.value("enabled", false).toBool();
103     pe.from_time = settings.value("from_time").toTime();
104     pe.to_time = settings.value("to_time").toTime();
105     pe.days << EVERY_DAY;
106     // Cookies
107     long from_cookie = settings.value("silencing_cookie", 0).toLongLong();
108     if(from_cookie > 0)
109       pe.alarmd_cookies << from_cookie;
110     long to_cookie = settings.value("unsilencing_cookie", 0).toLongLong();
111     if(to_cookie > 0)
112       pe.alarmd_cookies << to_cookie;
113     known_cookies << pe.alarmd_cookies;
114     if(to_cookie <= 0 || from_cookie <= 0)
115       pe.activated = false;
116     events.insert(pe.getID(), pe.save());
117     // Remove old format values
118     settings.clear();
119     // Save in new format
120     settings.setValue("events", events);
121   }
122   // Load >= v0.6 settings
123   bool settings_change = false;
124   foreach(QVariant e, events.values()) {
125     ProfileEvent *pe = ProfileEvent::load(e);
126     known_cookies << pe->alarmd_cookies;
127     // Check if still active
128     if(pe->activated && !AlarmdBackend::checkIfStillActive(pe)) {
129       qDebug("An existing profile switching event is no longer active, updating its status");
130       pe->activated = false;
131       events[pe->getID()] = pe->save();
132       settings_change = true;
133     }
134     // Add new model row
135     const int nb_rows = model->rowCount();
136     model->setRowCount(nb_rows+1);
137     updateRow(nb_rows, pe);
138     // Clean up
139     delete pe;
140   }
141   // Delete possible orphan events
142   AlarmdBackend::deleteOrphanEvents(known_cookies);
143   if(settings_change)
144     settings.setValue("events", events);
145 }
146
147 void SwitchingEventList::addNewEvent(QVariant var_event) {
148   qDebug("Adding a new event to the list");
149   ProfileEvent *pe = ProfileEvent::load(var_event);
150   // Add new model row
151   const int nb_rows = model->rowCount();
152   model->setRowCount(nb_rows+1);
153   updateRow(nb_rows, pe);
154   delete pe;
155 }
156
157 void SwitchingEventList::editEvent(QByteArray id, bool new_status) {
158   const int row = getRowFromID(id);
159   qDebug("Editing event at row %d", row);
160   Q_ASSERT(row >= 0);
161   model->setData(model->index(row, EV_STATUS), new_status, Qt::UserRole);
162 }
163
164 void SwitchingEventList::deleteEvent(QByteArray id) {
165   const int row = getRowFromID(id);
166   qDebug("Deleting an event (row: %d)", row);
167   Q_ASSERT(row >= 0);
168   model->removeRow(row);
169 }
170
171 int SwitchingEventList::getRowFromID(QByteArray id) {
172   for(int i=0; i<model->rowCount(); ++i) {
173     if(model->data(model->index(i, EV_ID)).toByteArray() == id)
174       return i;
175   }
176   return -1;
177 }