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 useConference(Conference::activeConference());
101 // optimization, see useConference() code
104 } catch (const OrmException& e) {
105 qDebug() << "OrmException:" << e.text();
109 // open dialog for given Event ID
110 // this is used in case Alarm Dialog request application to start
115 EventDialog dialog(aEventId,this);
118 catch(OrmNoObjectException&) {} // just start application
119 catch(...) {} // just start application
122 connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
124 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
125 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
128 void MainWindow::on_aboutAction_triggered()
130 QDialog dialog(this);
133 ui.labDescription->setText(ui.labDescription->text().arg(qApp->applicationVersion()));
135 dialog.setFixedWidth(width());
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());
151 void MainWindow::on_nowAction_triggered() {
156 void MainWindow::on_searchAction_triggered() {
157 searchTabContainer->showSearchDialog();
158 tabWidget->setCurrentWidget(searchTab);
162 void MainWindow::onEventChanged(int aEventId, bool favouriteChanged) {
163 dayTabContainer->redisplayEvent(aEventId);
164 if (favouriteChanged) favsTabContainer->redisplayDate(dayNavigator->curDate());
165 else favsTabContainer->redisplayEvent(aEventId);
166 tracksTabContainer->redisplayEvent(aEventId);
167 roomsTabContainer->redisplayEvent(aEventId);
168 searchTabContainer->redisplayEvent(aEventId);
172 void MainWindow::useConference(int id)
174 if (id == -1) // in case no conference is active
180 Conference::getById(Conference::activeConference()).update("active",0);
181 Conference new_active = Conference::getById(id);
182 new_active.update("active",1);
184 // looks like it does not work at n900
185 setWindowTitle(new_active.title());
188 // dont run initTabs() here
189 // it takes much CPU, making travelling between conferences in ConferenceEditor longer
190 // and is not seen in maemo WM anyway
191 // instead run it explicitly
193 // 2. when ConferenceEditor finished
194 // dont forget to protect the calls by try-catch!
196 // just in case, clear conference selection instead
199 // end of optimization
201 } catch (OrmException& e) {
202 // cannon set an active conference
203 unsetConference(); // TODO: as no active conference is now correctly managed this should be handled as a fatal error
209 void MainWindow::initTabs()
211 int confId = Conference::activeConference();
212 if (confId != -1) // only init tabs if a conference is active
214 Conference active = Conference::getById(confId);
215 QDate startDate = active.start();
216 QDate endDate = active.end();
218 // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
219 dayNavigator->setDates(startDate, endDate);
223 void MainWindow::clearTabs()
225 dayTabContainer->clearModel();
226 tracksTabContainer->clearModel();
227 roomsTabContainer->clearModel();
228 favsTabContainer->clearModel();
229 searchTabContainer->clearModel();
232 void MainWindow::unsetConference()
235 dayNavigator->unsetDates();
236 setWindowTitle(saved_title);
239 void MainWindow::on_settingsAction_triggered()
241 SettingsDialog dialog;
242 dialog.loadDialogData();
243 if (dialog.exec() == QDialog::Accepted) {
244 dialog.saveDialogData();
246 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
247 AppSettings::proxyAddress(),
248 AppSettings::proxyPort(),
251 QNetworkProxy::setApplicationProxy(proxy);
255 /** Create and run ConferenceEditor dialog, making required connections for it.
257 This method manages, which classes actually perform changes in conference list.
259 There are several classes that modify the conferences:
261 deletion and URL update.
262 this, mXmlParser and mNetworkAccessManager:
263 addition and refresh.
265 void MainWindow::on_conferencesAction_triggered()
267 ConferenceEditor dialog(conferenceModel, this);
269 connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
270 connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
271 connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
272 connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
273 SLOT(changeConferenceUrl(int, const QString&)));
275 connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
276 connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
278 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
279 connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
280 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
282 connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
286 // optimization, see useConference() code
289 } catch (OrmException) {
294 void MainWindow::networkQueryFinished(QNetworkReply *aReply)
296 if ( aReply->error() != QNetworkReply::NoError )
298 error_message(QString("Error occured during download: ") + aReply->errorString());
302 importData(aReply->readAll(), aReply->url().toEncoded());
307 void MainWindow::importData(const QByteArray &aData, const QString& url)
309 mXmlParser->parseData(aData, url);
312 void MainWindow::importFromNetwork(const QString& url)
314 QNetworkRequest request;
315 request.setUrl(QUrl(url));
317 mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
318 mNetworkAccessManager->get(request);
321 void MainWindow::importFromFile(const QString& filename)
323 QFile file(filename);
324 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
325 static const QString format("Cannot read \"%1\": error %2");
326 error_message(format.arg(filename, QString::number(file.error())));
329 importData(file.readAll(), "");
332 void MainWindow::removeConference(int id)
334 Conference::deleteConference(id);
335 conferenceModel->conferenceRemoved();
337 emit conferenceRemoved();
340 void MainWindow::changeConferenceUrl(int id, const QString& url)
342 Conference::getById(id).setUrl(url);