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::onEventChanged(int aEventId, bool favouriteChanged) {
170 dayTabContainer->redisplayEvent(aEventId);
171 if (favouriteChanged) favsTabContainer->redisplayDate(dayNavigator->curDate());
172 else favsTabContainer->redisplayEvent(aEventId);
173 tracksTabContainer->redisplayEvent(aEventId);
174 roomsTabContainer->redisplayEvent(aEventId);
175 searchTabContainer->redisplayEvent(aEventId);
179 void MainWindow::onSearchResultChanged() {
180 // Are results found on the current date?
181 QDate date = dayNavigator->curDate();
182 int count = searchTabContainer->searchResultCount(date);
183 if (count > 0) {searchTabContainer->redisplayDate(date); return;}
185 // Are results found in the future?
186 for (date = date.addDays(1); date <= dayNavigator->endDate(); date = date.addDays(1)) {
187 int count = searchTabContainer->searchResultCount(date);
188 if (count > 0) {dayNavigator->setCurDate(date); return;}
191 // Are results found in the past?
192 for (date = dayNavigator->startDate(); date < dayNavigator->curDate(); date = date.addDays(1)) {
193 int count = searchTabContainer->searchResultCount(date);
194 if (count > 0) {dayNavigator->setCurDate(date); return;}
196 // No results were found
197 searchTabContainer->redisplayDate(dayNavigator->curDate());
201 void MainWindow::useConference(int id)
203 if (id == -1) // in case no conference is active
209 Conference::getById(Conference::activeConference()).update("active",0);
210 Conference new_active = Conference::getById(id);
211 new_active.update("active",1);
213 // looks like it does not work at n900
214 setWindowTitle(new_active.title());
217 // dont run initTabs() here
218 // it takes much CPU, making travelling between conferences in ConferenceEditor longer
219 // and is not seen in maemo WM anyway
220 // instead run it explicitly
222 // 2. when ConferenceEditor finished
223 // dont forget to protect the calls by try-catch!
225 // just in case, clear conference selection instead
228 // end of optimization
230 } catch (OrmException& e) {
231 // cannon set an active conference
232 unsetConference(); // TODO: as no active conference is now correctly managed this should be handled as a fatal error
238 void MainWindow::initTabs()
240 int confId = Conference::activeConference();
241 if (confId != -1) // only init tabs if a conference is active
243 Conference active = Conference::getById(confId);
244 QDate startDate = active.start();
245 QDate endDate = active.end();
247 // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
248 dayNavigator->setDates(startDate, endDate);
252 void MainWindow::clearTabs()
254 dayTabContainer->clearModel();
255 tracksTabContainer->clearModel();
256 roomsTabContainer->clearModel();
257 favsTabContainer->clearModel();
258 searchTabContainer->clearModel();
261 void MainWindow::unsetConference()
264 dayNavigator->unsetDates();
265 setWindowTitle(saved_title);
268 void MainWindow::on_settingsAction_triggered()
270 SettingsDialog dialog;
271 dialog.loadDialogData();
272 if (dialog.exec() == QDialog::Accepted) {
273 dialog.saveDialogData();
275 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
276 AppSettings::proxyAddress(),
277 AppSettings::proxyPort(),
280 QNetworkProxy::setApplicationProxy(proxy);
284 /** Create and run ConferenceEditor dialog, making required connections for it.
286 This method manages, which classes actually perform changes in conference list.
288 There are several classes that modify the conferences:
290 deletion and URL update.
291 this, mXmlParser and mNetworkAccessManager:
292 addition and refresh.
294 void MainWindow::on_conferencesAction_triggered()
296 ConferenceEditor dialog(conferenceModel, this);
298 connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
299 connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
300 connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
301 connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
302 SLOT(changeConferenceUrl(int, const QString&)));
304 connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
305 connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
307 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
308 connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
309 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
311 connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
315 // optimization, see useConference() code
318 } catch (OrmException) {
323 void MainWindow::networkQueryFinished(QNetworkReply *aReply)
325 if ( aReply->error() != QNetworkReply::NoError )
327 error_message(QString("Error occured during download: ") + aReply->errorString());
331 importData(aReply->readAll(), aReply->url().toEncoded());
336 void MainWindow::importData(const QByteArray &aData, const QString& url)
338 mXmlParser->parseData(aData, url);
341 void MainWindow::importFromNetwork(const QString& url)
343 QNetworkRequest request;
344 request.setUrl(QUrl(url));
346 mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
347 mNetworkAccessManager->get(request);
350 void MainWindow::importFromFile(const QString& filename)
352 QFile file(filename);
353 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
354 static const QString format("Cannot read \"%1\": error %2");
355 error_message(format.arg(filename, QString::number(file.error())));
358 importData(file.readAll(), "");
361 void MainWindow::removeConference(int id)
363 Conference::deleteConference(id);
364 conferenceModel->conferenceRemoved();
366 emit conferenceRemoved();
369 void MainWindow::changeConferenceUrl(int id, const QString& url)
371 Conference::getById(id).setUrl(url);