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 // TODO: open conferences at startup?
118 tabWidget->setCurrentIndex(6); // 6 - conference tab
122 // open dialog for given Event ID
123 // this is used in case Alarm Dialog request application to start
128 EventDialog dialog(aEventId,this);
131 catch(OrmNoObjectException&) {} // just start application
132 catch(...) {} // just start application
135 connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
137 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
138 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
141 void MainWindow::aboutApp()
143 QDialog dialog(this);
146 ui.labDescription->setText(ui.labDescription->text().arg(qApp->applicationVersion()));
148 dialog.setFixedWidth(width());
153 void MainWindow::eventHasChanged(int aEventId, bool aReloadModel)
155 dayTabContainer->updateTreeViewModel(aEventId);
156 favsTabContainer->updateTreeViewModel(aEventId,aReloadModel);
157 tracksTabContainer->updateTreeViewModel(aEventId);
158 nowTabContainer->updateTreeViewModel(aEventId);
159 roomsTabContainer->updateTreeViewModel(aEventId);
160 searchTabContainer->updateTreeViewModel(aEventId);
163 void MainWindow::useConference(int id)
165 if (id == -1) // in case no conference is active
171 Conference::getById(Conference::activeConference()).update("active",0);
172 Conference new_active = Conference::getById(id);
173 new_active.update("active",1);
175 // looks like it does not work at n900
176 setWindowTitle(new_active.title());
179 // dont run initTabs() here
180 // it takes much CPU, making travelling between conferences in ConferenceEditor longer
181 // and is not seen in maemo WM anyway
182 // instead run it explicitly
184 // 2. when ConferenceEditor finished
185 // dont forget to protect the calls by try-catch!
187 // just in case, clear conference selection instead
190 // end of optimization
192 } catch (OrmException& e) {
193 // cannon set an active conference
194 unsetConference(); // TODO: as no active conference is now correctly managed this should be handled as a fatal error
200 void MainWindow::initTabs()
202 int confId = Conference::activeConference();
203 if (confId != -1) // only init tabs if a conference is active
205 Conference active = Conference::getById(confId);
206 QDate startDate = active.start();
207 QDate endDate = active.end();
209 // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
210 dayTabContainer->setDates(startDate, endDate);
211 tracksTabContainer->setDates(startDate, endDate);
212 roomsTabContainer->setDates(startDate, endDate);
213 favsTabContainer->setDates(startDate, endDate);
214 searchTabContainer->setDates(startDate, endDate);
215 searchTabContainer->searchAgainClicked();
216 nowTabContainer->updateTreeView(QDate::currentDate());
220 void MainWindow::clearTabs()
222 dayTabContainer->clearModel();
223 tracksTabContainer->clearModel();
224 roomsTabContainer->clearModel();
225 favsTabContainer->clearModel();
226 searchTabContainer->clearModel();
227 searchTabContainer->searchAgainClicked();
228 nowTabContainer->clearModel();
231 void MainWindow::unsetConference()
234 setWindowTitle(saved_title);
237 void MainWindow::setup()
239 SettingsDialog dialog;
240 dialog.loadDialogData();
241 if (dialog.exec() == QDialog::Accepted) {
242 dialog.saveDialogData();
244 AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
245 AppSettings::proxyAddress(),
246 AppSettings::proxyPort(),
249 QNetworkProxy::setApplicationProxy(proxy);
253 /** Create and run ConferenceEditor dialog, making required connections for it.
255 This method manages, which classes actually perform changes in conference list.
257 There are several classes that modify the conferences:
259 deletion and URL update.
260 this, mXmlParser and mNetworkAccessManager:
261 addition and refresh.
263 void MainWindow::showConferences()
265 ConferenceEditor dialog(conferenceModel, this);
267 connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
268 connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
269 connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
270 connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
271 SLOT(changeConferenceUrl(int, const QString&)));
273 connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
274 connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
276 connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
277 connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
278 connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
280 connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
284 // optimization, see useConference() code
287 } catch (OrmException) {
292 void MainWindow::networkQueryFinished(QNetworkReply *aReply)
294 if ( aReply->error() != QNetworkReply::NoError )
296 error_message(QString("Error occured during download: ") + aReply->errorString());
300 importData(aReply->readAll(), aReply->url().toEncoded());
304 void MainWindow::importData(const QByteArray &aData, const QString& url)
306 mXmlParser->parseData(aData, url);
309 void MainWindow::importFromNetwork(const QString& url)
311 QNetworkRequest request;
312 request.setUrl(QUrl(url));
314 mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
315 mNetworkAccessManager->get(request);
318 void MainWindow::importFromFile(const QString& filename)
320 QFile file(filename);
321 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
322 static const QString format("Cannot read \"%1\": error %2");
323 error_message(format.arg(filename, QString::number(file.error())));
326 importData(file.readAll(), "");
329 void MainWindow::removeConference(int id)
331 Conference::deleteConference(id);
332 conferenceModel->conferenceRemoved();
334 emit conferenceRemoved();
337 void MainWindow::changeConferenceUrl(int id, const QString& url)
339 Conference::getById(id).setUrl(url);