2 * Copyright (C) 2010 Ixonos Plc.
4 * This file is part of fosdem-schedule.
6 * fosdem-schedule is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 2 of the License, or (at your option)
11 * fosdem-schedule is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * fosdem-schedule. If not, see <http://www.gnu.org/licenses/>.
19 #include "mainwindow.h"
23 #include <QNetworkProxy>
24 #include <QNetworkAccessManager>
25 #include <QNetworkReply>
27 #include <sqlengine.h>
30 #include <eventmodel.h>
33 #include <conference.h>
36 #include <QMessageBox>
39 #include <eventdialog.h>
40 #include "daynavigatorwidget.h"
41 #include "mapwindow.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);
72 if(AppSettings::isDirectConnection())
74 qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
77 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
78 AppSettings::proxyAddress(),
79 AppSettings::proxyPort(),
82 QNetworkProxy::setApplicationProxy(proxy);
84 // event details have changed
85 connect(dayTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
86 connect(favsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
87 connect(tracksTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
88 connect(roomsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
89 connect(nowTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
90 connect(searchTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
92 connect(aboutAction, SIGNAL(triggered()), SLOT(aboutApp()));
93 connect(settingsAction, SIGNAL(triggered()), SLOT(setup()));
94 connect(conferencesAction, SIGNAL(triggered()), SLOT(showConferences()));
96 useConference(Conference::activeConference());
97 // optimization, see useConference() code
100 } catch (OrmException) {
104 // TODO: open conferences at startup?
107 tabWidget->setCurrentIndex(6); // 6 - conference tab
111 // open dialog for given Event ID
112 // this is used in case Alarm Dialog request application to start
117 EventDialog dialog(aEventId,this);
120 catch(OrmNoObjectException&) {} // just start application
121 catch(...) {} // just start application
124 connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
126 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
127 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
130 void MainWindow::aboutApp()
132 QDialog dialog(this);
136 dialog.setFixedWidth(width());
141 void MainWindow::conferenceMapClicked()
143 QString mapPath = QString(":/maps/campus.png");
144 if(!QFile::exists(mapPath))
145 mapPath = QString(":/maps/rooms/not-available.png");
149 QPixmap map(mapPath);
150 MapWindow window(map,roomName,this);
154 void MainWindow::eventHasChanged(int aEventId, bool aReloadModel)
156 dayTabContainer->updateTreeViewModel(aEventId);
157 favsTabContainer->updateTreeViewModel(aEventId,aReloadModel);
158 tracksTabContainer->updateTreeViewModel(aEventId);
159 nowTabContainer->updateTreeViewModel(aEventId);
160 roomsTabContainer->updateTreeViewModel(aEventId);
161 searchTabContainer->updateTreeViewModel(aEventId);
164 void MainWindow::useConference(int id)
167 Conference::getById(Conference::activeConference()).update("active",0);
168 Conference new_active = Conference::getById(id);
169 new_active.update("active",1);
171 // looks like it does not work at n900
172 setWindowTitle(new_active.title());
175 // dont run initTabs() here
176 // it takes much CPU, making travelling between conferences in ConferenceEditor longer
177 // and is not seen in maemo WM anyway
178 // instead run it explicitly
180 // 2. when ConferenceEditor finished
181 // dont forget to protect the calls by try-catch!
183 // just in case, clear conference selection instead
186 // end of optimization
188 } catch (OrmException& e) {
189 // cannon set an active conference
196 void MainWindow::initTabs()
198 int confId = Conference::activeConference();
199 Conference active = Conference::getById(confId);
200 QDate startDate = active.start();
201 QDate endDate = active.end();
203 // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
204 dayTabContainer->setDates(startDate, endDate);
205 tracksTabContainer->setDates(startDate, endDate);
206 roomsTabContainer->setDates(startDate, endDate);
207 favsTabContainer->setDates(startDate, endDate);
208 searchTabContainer->setDates(startDate, endDate);
209 searchTabContainer->searchAgainClicked();
210 nowTabContainer->updateTreeView(QDate::currentDate());
213 void MainWindow::clearTabs()
215 dayTabContainer->clearModel();
216 tracksTabContainer->clearModel();
217 roomsTabContainer->clearModel();
218 favsTabContainer->clearModel();
219 searchTabContainer->clearModel();
220 searchTabContainer->searchAgainClicked();
221 nowTabContainer->clearModel();
224 void MainWindow::unsetConference()
227 setWindowTitle(saved_title);
230 void MainWindow::setup()
232 SettingsDialog dialog;
235 qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
237 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
238 AppSettings::proxyAddress(),
239 AppSettings::proxyPort(),
242 QNetworkProxy::setApplicationProxy(proxy);
245 /** Create and run ConferenceEditor dialog, making required connections for it.
247 This method manages, which classes actually perform changes in conference list.
249 There are several classes that modify the conferences:
251 deletion and URL update.
252 this, mXmlParser and mNetworkAccessManager:
253 addition and refresh.
255 void MainWindow::showConferences()
257 ConferenceEditor dialog(conferenceModel, this);
259 connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
260 connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
261 connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
262 connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
263 SLOT(changeConferenceUrl(int, const QString&)));
265 connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
266 connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
268 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
269 connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
270 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
272 connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
274 // TODO: propagate press of showMapButton here
275 // connect(showMapButton, SIGNAL(clicked()), SLOT(conferenceMapClicked()));
279 // optimization, see useConference() code
282 } catch (OrmException) {
287 void MainWindow::networkQueryFinished(QNetworkReply *aReply)
289 if ( aReply->error() != QNetworkReply::NoError )
291 error_message(QString("Error occured during download: ") + aReply->errorString());
295 qDebug() << __PRETTY_FUNCTION__ << ": have data";
296 importData(aReply->readAll(), aReply->url().toEncoded());
300 void MainWindow::importData(const QByteArray &aData, const QString& url)
302 mXmlParser->parseData(aData, url);
305 void MainWindow::importFromNetwork(const QString& url)
307 qDebug() << __PRETTY_FUNCTION__;
308 QNetworkRequest request;
309 request.setUrl(QUrl(url));
311 mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
312 mNetworkAccessManager->get(request);
315 void MainWindow::importFromFile(const QString& filename)
317 qDebug() << __PRETTY_FUNCTION__;
318 QFile file(filename);
319 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
320 static const QString format("Cannot read \"%1\": error %2");
321 error_message(format.arg(filename, QString::number(file.error())));
324 importData(file.readAll(), "");
327 void MainWindow::removeConference(int id)
329 Conference::deleteConference(id);
330 conferenceModel->conferenceRemoved();
332 emit conferenceRemoved();
335 void MainWindow::changeConferenceUrl(int id, const QString& url)
337 Conference::getById(id).setUrl(url);