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() {
152 int confId = Conference::activeConference();
153 if (confId== -1) return;
154 dayNavigator->setCurDate(QDate::currentDate());
155 dayTabContainer->expandTimeGroup(QTime::currentTime(), confId);
159 void MainWindow::on_searchAction_triggered() {
160 searchTabContainer->showSearchDialog();
161 tabWidget->setCurrentWidget(searchTab);
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);
175 void MainWindow::useConference(int id)
177 if (id == -1) // in case no conference is active
183 Conference::getById(Conference::activeConference()).update("active",0);
184 Conference new_active = Conference::getById(id);
185 new_active.update("active",1);
187 // looks like it does not work at n900
188 setWindowTitle(new_active.title());
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
196 // 2. when ConferenceEditor finished
197 // dont forget to protect the calls by try-catch!
199 // just in case, clear conference selection instead
202 // end of optimization
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
212 void MainWindow::initTabs()
214 int confId = Conference::activeConference();
215 if (confId != -1) // only init tabs if a conference is active
217 Conference active = Conference::getById(confId);
218 QDate startDate = active.start();
219 QDate endDate = active.end();
221 // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
222 dayNavigator->setDates(startDate, endDate);
226 void MainWindow::clearTabs()
228 dayTabContainer->clearModel();
229 tracksTabContainer->clearModel();
230 roomsTabContainer->clearModel();
231 favsTabContainer->clearModel();
232 searchTabContainer->clearModel();
235 void MainWindow::unsetConference()
238 dayNavigator->unsetDates();
239 setWindowTitle(saved_title);
242 void MainWindow::on_settingsAction_triggered()
244 SettingsDialog dialog;
245 dialog.loadDialogData();
246 if (dialog.exec() == QDialog::Accepted) {
247 dialog.saveDialogData();
249 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
250 AppSettings::proxyAddress(),
251 AppSettings::proxyPort(),
254 QNetworkProxy::setApplicationProxy(proxy);
258 /** Create and run ConferenceEditor dialog, making required connections for it.
260 This method manages, which classes actually perform changes in conference list.
262 There are several classes that modify the conferences:
264 deletion and URL update.
265 this, mXmlParser and mNetworkAccessManager:
266 addition and refresh.
268 void MainWindow::on_conferencesAction_triggered()
270 ConferenceEditor dialog(conferenceModel, this);
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&)));
278 connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
279 connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
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&)));
285 connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
289 // optimization, see useConference() code
292 } catch (OrmException) {
297 void MainWindow::networkQueryFinished(QNetworkReply *aReply)
299 if ( aReply->error() != QNetworkReply::NoError )
301 error_message(QString("Error occured during download: ") + aReply->errorString());
305 importData(aReply->readAll(), aReply->url().toEncoded());
310 void MainWindow::importData(const QByteArray &aData, const QString& url)
312 mXmlParser->parseData(aData, url);
315 void MainWindow::importFromNetwork(const QString& url)
317 QNetworkRequest request;
318 request.setUrl(QUrl(url));
320 mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
321 mNetworkAccessManager->get(request);
324 void MainWindow::importFromFile(const QString& filename)
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())));
332 importData(file.readAll(), "");
335 void MainWindow::removeConference(int id)
337 Conference::deleteConference(id);
338 conferenceModel->conferenceRemoved();
340 emit conferenceRemoved();
343 void MainWindow::changeConferenceUrl(int id, const QString& url)
345 Conference::getById(id).setUrl(url);