2 * Copyright (C) 2010 Ixonos Plc.
3 * Copyright (C) 2011 Philipp Spitzer, gregor herrmann
5 * This file is part of ConfClerk.
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)
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
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/>.
20 #include "mainwindow.h"
24 #include <QNetworkProxy>
25 #include <QNetworkAccessManager>
26 #include <QNetworkReply>
28 #include <sqlengine.h>
31 #include <eventmodel.h>
34 #include <conference.h>
37 #include <QMessageBox>
40 #include <eventdialog.h>
41 #include "daynavigatorwidget.h"
42 #include "settingsdialog.h"
43 #include "conferenceeditor.h"
44 #include "schedulexmlparser.h"
45 #include "errormessage.h"
47 #include <tabcontainer.h>
48 #include <appsettings.h>
50 const QString PROXY_USERNAME;
51 const QString PROXY_PASSWD;
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))
61 saved_title = windowTitle();
64 tabWidget->setTabText(1,"Favs");
65 //tabWidget->setTabText(2,"Day");
68 // first time run aplication: -> let's have it direct connection in this case
69 if(!AppSettings::contains("proxyIsDirectConnection"))
70 AppSettings::setDirectConnection(true);
73 if(AppSettings::isDirectConnection())
75 qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
79 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
80 AppSettings::proxyAddress(),
81 AppSettings::proxyPort(),
84 QNetworkProxy::setApplicationProxy(proxy);
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)));
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)));
100 // search result has changed
101 connect(searchTabContainer, SIGNAL(searchResultChanged()), SLOT(onSearchResultChanged()));
104 useConference(Conference::activeConference());
105 // optimization, see useConference() code
108 } catch (const OrmException& e) {
109 qDebug() << "OrmException:" << e.text();
113 // open dialog for given Event ID
114 // this is used in case Alarm Dialog request application to start
119 EventDialog dialog(aEventId,this);
122 catch(OrmNoObjectException&) {} // just start application
123 catch(...) {} // just start application
126 connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
128 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
129 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
132 void MainWindow::on_aboutAction_triggered()
134 QDialog dialog(this);
137 ui.labDescription->setText(ui.labDescription->text().arg(qApp->applicationVersion()));
139 dialog.setFixedWidth(width());
145 void MainWindow::on_reloadAction_triggered() {
146 int confId = Conference::activeConference();
147 if (confId== -1) return;
148 Conference active = Conference::getById(confId);
149 if (active.url().isEmpty()) return;
150 importFromNetwork(active.url());
155 void MainWindow::on_nowAction_triggered() {
156 int confId = Conference::activeConference();
157 if (confId== -1) return;
158 dayNavigator->setCurDate(QDate::currentDate());
159 dayTabContainer->expandTimeGroup(QTime::currentTime(), confId);
163 void MainWindow::on_searchAction_triggered() {
164 searchTabContainer->showSearchDialog();
165 tabWidget->setCurrentWidget(searchTab);
169 void MainWindow::on_expandAllAction_triggered() {
174 void MainWindow::on_collapseAllAction_triggered() {
179 void MainWindow::onEventChanged(int aEventId, bool favouriteChanged) {
180 dayTabContainer->redisplayEvent(aEventId);
181 if (favouriteChanged) favsTabContainer->redisplayDate(dayNavigator->curDate());
182 else favsTabContainer->redisplayEvent(aEventId);
183 tracksTabContainer->redisplayEvent(aEventId);
184 roomsTabContainer->redisplayEvent(aEventId);
185 searchTabContainer->redisplayEvent(aEventId);
189 void MainWindow::onSearchResultChanged() {
190 // Are results found on the current date?
191 QDate date = dayNavigator->curDate();
192 int count = searchTabContainer->searchResultCount(date);
193 if (count > 0) {searchTabContainer->redisplayDate(date); return;}
195 // Are results found in the future?
196 for (date = date.addDays(1); date <= dayNavigator->endDate(); date = date.addDays(1)) {
197 int count = searchTabContainer->searchResultCount(date);
198 if (count > 0) {dayNavigator->setCurDate(date); return;}
201 // Are results found in the past?
202 for (date = dayNavigator->startDate(); date < dayNavigator->curDate(); date = date.addDays(1)) {
203 int count = searchTabContainer->searchResultCount(date);
204 if (count > 0) {dayNavigator->setCurDate(date); return;}
206 // No results were found
207 searchTabContainer->redisplayDate(dayNavigator->curDate());
211 void MainWindow::useConference(int id)
213 if (id == -1) // in case no conference is active
219 Conference::getById(Conference::activeConference()).update("active",0);
220 Conference new_active = Conference::getById(id);
221 new_active.update("active",1);
223 // looks like it does not work at n900
224 setWindowTitle(new_active.title());
227 // dont run initTabs() here
228 // it takes much CPU, making travelling between conferences in ConferenceEditor longer
229 // and is not seen in maemo WM anyway
230 // instead run it explicitly
232 // 2. when ConferenceEditor finished
233 // dont forget to protect the calls by try-catch!
235 // just in case, clear conference selection instead
238 // end of optimization
240 } catch (OrmException& e) {
241 // cannon set an active conference
242 unsetConference(); // TODO: as no active conference is now correctly managed this should be handled as a fatal error
248 void MainWindow::initTabs()
250 int confId = Conference::activeConference();
251 if (confId != -1) // only init tabs if a conference is active
253 Conference active = Conference::getById(confId);
254 QDate startDate = active.start();
255 QDate endDate = active.end();
257 // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
258 dayNavigator->setDates(startDate, endDate);
262 void MainWindow::clearTabs()
264 dayTabContainer->clearModel();
265 tracksTabContainer->clearModel();
266 roomsTabContainer->clearModel();
267 favsTabContainer->clearModel();
268 searchTabContainer->clearModel();
271 void MainWindow::unsetConference()
274 dayNavigator->unsetDates();
275 setWindowTitle(saved_title);
278 void MainWindow::on_settingsAction_triggered()
280 SettingsDialog dialog;
281 dialog.loadDialogData();
282 if (dialog.exec() == QDialog::Accepted) {
283 dialog.saveDialogData();
285 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
286 AppSettings::proxyAddress(),
287 AppSettings::proxyPort(),
290 QNetworkProxy::setApplicationProxy(proxy);
294 /** Create and run ConferenceEditor dialog, making required connections for it.
296 This method manages, which classes actually perform changes in conference list.
298 There are several classes that modify the conferences:
300 deletion and URL update.
301 this, mXmlParser and mNetworkAccessManager:
302 addition and refresh.
304 void MainWindow::on_conferencesAction_triggered()
306 ConferenceEditor dialog(conferenceModel, this);
308 connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
309 connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
310 connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
311 connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
312 SLOT(changeConferenceUrl(int, const QString&)));
314 connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
315 connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
317 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
318 connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
319 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
321 connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
325 // optimization, see useConference() code
328 } catch (OrmException) {
333 void MainWindow::networkQueryFinished(QNetworkReply *aReply)
335 if ( aReply->error() != QNetworkReply::NoError )
337 error_message(QString("Error occured during download: ") + aReply->errorString());
341 importData(aReply->readAll(), aReply->url().toEncoded());
346 void MainWindow::importData(const QByteArray &aData, const QString& url)
348 mXmlParser->parseData(aData, url);
351 void MainWindow::importFromNetwork(const QString& url)
353 QNetworkRequest request;
354 request.setUrl(QUrl(url));
356 mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
357 mNetworkAccessManager->get(request);
360 void MainWindow::importFromFile(const QString& filename)
362 QFile file(filename);
363 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
364 static const QString format("Cannot read \"%1\": error %2");
365 error_message(format.arg(filename, QString::number(file.error())));
368 importData(file.readAll(), "");
371 void MainWindow::removeConference(int id)
373 Conference::deleteConference(id);
374 conferenceModel->conferenceRemoved();
376 emit conferenceRemoved();
379 void MainWindow::changeConferenceUrl(int id, const QString& url)
381 Conference::getById(id).setUrl(url);