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(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
88 connect(favsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
89 connect(tracksTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
90 connect(roomsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
91 connect(nowTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
92 connect(searchTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
95 connect(dayNavigator, SIGNAL(dateChanged(QDate)), dayTabContainer, SLOT(setCurDate(QDate)));
96 connect(dayNavigator, SIGNAL(dateChanged(QDate)), favsTabContainer, SLOT(setCurDate(QDate)));
97 connect(dayNavigator, SIGNAL(dateChanged(QDate)), tracksTabContainer, SLOT(setCurDate(QDate)));
98 connect(dayNavigator, SIGNAL(dateChanged(QDate)), roomsTabContainer, SLOT(setCurDate(QDate)));
99 connect(dayNavigator, SIGNAL(dateChanged(QDate)), nowTabContainer, SLOT(setCurDate(QDate)));
100 connect(dayNavigator, SIGNAL(dateChanged(QDate)), searchTabContainer, SLOT(setCurDate(QDate)));
102 connect(aboutAction, SIGNAL(triggered()), SLOT(aboutApp()));
103 connect(settingsAction, SIGNAL(triggered()), SLOT(setup()));
104 connect(conferencesAction, SIGNAL(triggered()), SLOT(showConferences()));
106 useConference(Conference::activeConference());
107 // optimization, see useConference() code
110 } catch (const OrmException& e) {
111 qDebug() << "OrmException:" << e.text();
115 // open dialog for given Event ID
116 // this is used in case Alarm Dialog request application to start
121 EventDialog dialog(aEventId,this);
124 catch(OrmNoObjectException&) {} // just start application
125 catch(...) {} // just start application
128 connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
130 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
131 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
134 void MainWindow::aboutApp()
136 QDialog dialog(this);
139 ui.labDescription->setText(ui.labDescription->text().arg(qApp->applicationVersion()));
141 dialog.setFixedWidth(width());
146 void MainWindow::eventHasChanged(int aEventId, bool aReloadModel)
148 dayTabContainer->updateTreeViewModel(aEventId);
149 favsTabContainer->updateTreeViewModel(aEventId,aReloadModel);
150 tracksTabContainer->updateTreeViewModel(aEventId);
151 nowTabContainer->updateTreeViewModel(aEventId);
152 roomsTabContainer->updateTreeViewModel(aEventId);
153 searchTabContainer->updateTreeViewModel(aEventId);
156 void MainWindow::useConference(int id)
158 if (id == -1) // in case no conference is active
164 Conference::getById(Conference::activeConference()).update("active",0);
165 Conference new_active = Conference::getById(id);
166 new_active.update("active",1);
168 // looks like it does not work at n900
169 setWindowTitle(new_active.title());
172 // dont run initTabs() here
173 // it takes much CPU, making travelling between conferences in ConferenceEditor longer
174 // and is not seen in maemo WM anyway
175 // instead run it explicitly
177 // 2. when ConferenceEditor finished
178 // dont forget to protect the calls by try-catch!
180 // just in case, clear conference selection instead
183 // end of optimization
185 } catch (OrmException& e) {
186 // cannon set an active conference
187 unsetConference(); // TODO: as no active conference is now correctly managed this should be handled as a fatal error
193 void MainWindow::initTabs()
195 int confId = Conference::activeConference();
196 if (confId != -1) // only init tabs if a conference is active
198 Conference active = Conference::getById(confId);
199 QDate startDate = active.start();
200 QDate endDate = active.end();
202 // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
203 dayTabContainer->setDates(startDate, endDate);
204 tracksTabContainer->setDates(startDate, endDate);
205 roomsTabContainer->setDates(startDate, endDate);
206 favsTabContainer->setDates(startDate, endDate);
207 searchTabContainer->setDates(startDate, endDate);
208 searchTabContainer->searchAgainClicked();
209 nowTabContainer->updateTreeView(QDate::currentDate());
210 dayNavigator->setDates(startDate, endDate);
214 void MainWindow::clearTabs()
216 dayTabContainer->clearModel();
217 tracksTabContainer->clearModel();
218 roomsTabContainer->clearModel();
219 favsTabContainer->clearModel();
220 searchTabContainer->clearModel();
221 searchTabContainer->searchAgainClicked();
222 nowTabContainer->clearModel();
225 void MainWindow::unsetConference()
228 dayNavigator->unsetDates();
229 setWindowTitle(saved_title);
232 void MainWindow::setup()
234 SettingsDialog dialog;
235 dialog.loadDialogData();
236 if (dialog.exec() == QDialog::Accepted) {
237 dialog.saveDialogData();
239 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
240 AppSettings::proxyAddress(),
241 AppSettings::proxyPort(),
244 QNetworkProxy::setApplicationProxy(proxy);
248 /** Create and run ConferenceEditor dialog, making required connections for it.
250 This method manages, which classes actually perform changes in conference list.
252 There are several classes that modify the conferences:
254 deletion and URL update.
255 this, mXmlParser and mNetworkAccessManager:
256 addition and refresh.
258 void MainWindow::showConferences()
260 ConferenceEditor dialog(conferenceModel, this);
262 connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
263 connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
264 connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
265 connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
266 SLOT(changeConferenceUrl(int, const QString&)));
268 connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
269 connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
271 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
272 connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
273 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
275 connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
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 importData(aReply->readAll(), aReply->url().toEncoded());
299 void MainWindow::importData(const QByteArray &aData, const QString& url)
301 mXmlParser->parseData(aData, url);
304 void MainWindow::importFromNetwork(const QString& url)
306 QNetworkRequest request;
307 request.setUrl(QUrl(url));
309 mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
310 mNetworkAccessManager->get(request);
313 void MainWindow::importFromFile(const QString& filename)
315 QFile file(filename);
316 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
317 static const QString format("Cannot read \"%1\": error %2");
318 error_message(format.arg(filename, QString::number(file.error())));
321 importData(file.readAll(), "");
324 void MainWindow::removeConference(int id)
326 Conference::deleteConference(id);
327 conferenceModel->conferenceRemoved();
329 emit conferenceRemoved();
332 void MainWindow::changeConferenceUrl(int id, const QString& url)
334 Conference::getById(id).setUrl(url);