]> ToastFreeware Gitweb - toast/confclerk.git/blob - src/gui/mainwindow.cpp
Implemented "now" action and removed the "now" button from the day navigator.
[toast/confclerk.git] / src / gui / mainwindow.cpp
1 /*
2  * Copyright (C) 2010 Ixonos Plc.
3  * Copyright (C) 2011 Philipp Spitzer, gregor herrmann
4  *
5  * This file is part of ConfClerk.
6  *
7  * ConfClerk is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation, either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * ConfClerk is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 #include "mainwindow.h"
21
22 #include <QTreeView>
23 #include <QFile>
24 #include <QNetworkProxy>
25 #include <QNetworkAccessManager>
26 #include <QNetworkReply>
27
28 #include <sqlengine.h>
29
30 #include <track.h>
31 #include <eventmodel.h>
32 #include <delegate.h>
33
34 #include <conference.h>
35
36 #include <QDialog>
37 #include <QMessageBox>
38
39 #include "ui_about.h"
40 #include <eventdialog.h>
41 #include "daynavigatorwidget.h"
42 #include "settingsdialog.h"
43 #include "conferenceeditor.h"
44 #include "schedulexmlparser.h"
45 #include "errormessage.h"
46
47 #include <tabcontainer.h>
48 #include <appsettings.h>
49
50 const QString PROXY_USERNAME;
51 const QString PROXY_PASSWD;
52
53 MainWindow::MainWindow(int aEventId, QWidget *aParent)
54     : QMainWindow(aParent)
55     , conferenceModel(new ConferenceModel(this))
56     , mXmlParser(new ScheduleXmlParser(this))
57     , mNetworkAccessManager(new QNetworkAccessManager(this))
58 {
59     setupUi(this);
60
61     saved_title = windowTitle();
62
63 #ifdef N810
64     tabWidget->setTabText(1,"Favs");
65     //tabWidget->setTabText(2,"Day");
66 #endif
67
68     // first time run aplication: -> let's have it direct connection in this case
69     if(!AppSettings::contains("proxyIsDirectConnection"))
70         AppSettings::setDirectConnection(true);
71
72     /*
73     if(AppSettings::isDirectConnection())
74     {
75         qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
76     }
77     */
78     QNetworkProxy proxy(
79             AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
80             AppSettings::proxyAddress(),
81             AppSettings::proxyPort(),
82             PROXY_USERNAME,
83             PROXY_PASSWD);
84     QNetworkProxy::setApplicationProxy(proxy);
85
86     // event details have changed
87     connect(dayTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
88     connect(favsTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
89     connect(tracksTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
90     connect(roomsTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
91     connect(searchTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
92
93     // date has changed
94     connect(dayNavigator, SIGNAL(dateChanged(QDate)), dayTabContainer, SLOT(redisplayDate(QDate)));
95     connect(dayNavigator, SIGNAL(dateChanged(QDate)), favsTabContainer, SLOT(redisplayDate(QDate)));
96     connect(dayNavigator, SIGNAL(dateChanged(QDate)), tracksTabContainer, SLOT(redisplayDate(QDate)));
97     connect(dayNavigator, SIGNAL(dateChanged(QDate)), roomsTabContainer, SLOT(redisplayDate(QDate)));
98     connect(dayNavigator, SIGNAL(dateChanged(QDate)), searchTabContainer, SLOT(redisplayDate(QDate)));
99
100     useConference(Conference::activeConference());
101     // optimization, see useConference() code
102     try {
103         initTabs();
104     } catch (const OrmException& e) {
105         qDebug() << "OrmException:" << e.text();
106         clearTabs();
107     }
108
109     // open dialog for given Event ID
110     // this is used in case Alarm Dialog request application to start
111     if(aEventId)
112     {
113         try
114         {
115             EventDialog dialog(aEventId,this);
116             dialog.exec();
117         }
118         catch(OrmNoObjectException&) {} // just start application
119         catch(...) {} // just start application
120     }
121
122     connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
123
124     connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
125     connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
126 }
127
128 void MainWindow::on_aboutAction_triggered()
129 {
130     QDialog dialog(this);
131     Ui::AboutDialog ui;
132     ui.setupUi(&dialog);
133     ui.labDescription->setText(ui.labDescription->text().arg(qApp->applicationVersion()));
134 #ifdef N810
135     dialog.setFixedWidth(width());
136 #endif
137     dialog.exec();
138 }
139
140
141 void MainWindow::on_reloadAction_triggered() {
142     int confId = Conference::activeConference();
143     if (confId== -1) return;
144     Conference active = Conference::getById(confId);
145     if (active.url().isEmpty()) return;
146     importFromNetwork(active.url());
147     setEnabled(false);
148 }
149
150
151 void MainWindow::on_nowAction_triggered() {
152     int confId = Conference::activeConference();
153     if (confId== -1) return;
154     dayNavigator->setCurDate(QDate::currentDate());
155     dayTabContainer->expandTimeGroup(QTime::currentTime(), confId);
156 }
157
158
159 void MainWindow::on_searchAction_triggered() {
160     searchTabContainer->showSearchDialog();
161     tabWidget->setCurrentWidget(searchTab);
162 }
163
164
165 void MainWindow::onEventChanged(int aEventId, bool favouriteChanged) {
166     dayTabContainer->redisplayEvent(aEventId);
167     if (favouriteChanged) favsTabContainer->redisplayDate(dayNavigator->curDate());
168     else favsTabContainer->redisplayEvent(aEventId);
169     tracksTabContainer->redisplayEvent(aEventId);
170     roomsTabContainer->redisplayEvent(aEventId);
171     searchTabContainer->redisplayEvent(aEventId);
172 }
173
174
175 void MainWindow::useConference(int id)
176 {
177     if (id == -1)  // in case no conference is active
178     {
179         unsetConference();
180         return;
181     }
182     try {
183         Conference::getById(Conference::activeConference()).update("active",0);
184         Conference new_active = Conference::getById(id);
185         new_active.update("active",1);
186
187         // looks like it does not work at n900
188         setWindowTitle(new_active.title());
189
190         // optimization.
191         // dont run initTabs() here
192         // it takes much CPU, making travelling between conferences in ConferenceEditor longer
193         // and is not seen in maemo WM anyway
194         // instead run it explicitly
195         // 1. at startup
196         // 2. when ConferenceEditor finished
197         // dont forget to protect the calls by try-catch!
198
199         // just in case, clear conference selection instead
200         clearTabs();
201
202         // end of optimization
203         // initTabs();
204     } catch (OrmException& e) {
205         // cannon set an active conference
206         unsetConference();   // TODO: as no active conference is now correctly managed this should be handled as a fatal error
207         return;
208     }
209
210 }
211
212 void MainWindow::initTabs()
213 {
214     int confId = Conference::activeConference();
215     if (confId != -1)   // only init tabs if a conference is active
216     {
217         Conference active = Conference::getById(confId);
218         QDate startDate = active.start();
219         QDate endDate = active.end();
220
221         // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
222         dayNavigator->setDates(startDate, endDate);
223     }
224 }
225
226 void MainWindow::clearTabs()
227 {
228     dayTabContainer->clearModel();
229     tracksTabContainer->clearModel();
230     roomsTabContainer->clearModel();
231     favsTabContainer->clearModel();
232     searchTabContainer->clearModel();
233 }
234
235 void MainWindow::unsetConference()
236 {
237     clearTabs();
238     dayNavigator->unsetDates();
239     setWindowTitle(saved_title);
240 }
241
242 void MainWindow::on_settingsAction_triggered()
243 {
244     SettingsDialog dialog;
245     dialog.loadDialogData();
246     if (dialog.exec() == QDialog::Accepted) {
247         dialog.saveDialogData();
248         QNetworkProxy proxy(
249                 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
250                 AppSettings::proxyAddress(),
251                 AppSettings::proxyPort(),
252                 PROXY_USERNAME,
253                 PROXY_PASSWD);
254         QNetworkProxy::setApplicationProxy(proxy);
255     }
256 }
257
258 /** Create and run ConferenceEditor dialog, making required connections for it.
259
260 This method manages, which classes actually perform changes in conference list.
261
262 There are several classes that modify the conferences:
263 this:
264  deletion and URL update.
265 this, mXmlParser and mNetworkAccessManager:
266  addition and refresh.
267 */
268 void MainWindow::on_conferencesAction_triggered()
269 {
270     ConferenceEditor dialog(conferenceModel, this);
271
272     connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
273     connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
274     connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
275     connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
276                     SLOT(changeConferenceUrl(int, const QString&)));
277
278     connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
279     connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
280
281     connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
282     connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
283     connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
284
285     connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
286
287     dialog.exec();
288
289     // optimization, see useConference() code
290     try {
291         initTabs();
292     } catch (OrmException) {
293         clearTabs();
294     }
295 }
296
297 void MainWindow::networkQueryFinished(QNetworkReply *aReply)
298 {
299     if ( aReply->error() != QNetworkReply::NoError )
300     {
301         error_message(QString("Error occured during download: ") + aReply->errorString());
302     }
303     else
304     {
305         importData(aReply->readAll(), aReply->url().toEncoded());
306     }
307     setEnabled(true);
308 }
309
310 void MainWindow::importData(const QByteArray &aData, const QString& url)
311 {
312     mXmlParser->parseData(aData, url);
313 }
314
315 void MainWindow::importFromNetwork(const QString& url)
316 {
317     QNetworkRequest request;
318     request.setUrl(QUrl(url));
319
320     mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
321     mNetworkAccessManager->get(request);
322 }
323
324 void MainWindow::importFromFile(const QString& filename)
325 {
326     QFile file(filename);
327     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {    
328         static const QString format("Cannot read \"%1\": error %2");
329         error_message(format.arg(filename, QString::number(file.error())));
330     }
331
332     importData(file.readAll(), "");
333 }
334
335 void MainWindow::removeConference(int id)
336 {
337     Conference::deleteConference(id);
338     conferenceModel->conferenceRemoved();
339
340     emit conferenceRemoved();
341 }
342
343 void MainWindow::changeConferenceUrl(int id, const QString& url)
344 {
345     Conference::getById(id).setUrl(url);
346 }
347