source: confclerk_git/src/gui/mainwindow.cpp @ e2c612c

qt5
Last change on this file since e2c612c was e2c612c, checked in by Philipp Spitzer <philipp@…>, 10 years ago

Reloading a conference works now.

  • Property mode set to 100644
File size: 14.1 KB
Line 
1/*
2 * Copyright (C) 2010 Ixonos Plc.
3 * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
4 *
5 * This file is part of ConfClerk.
6 *
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)
10 * any later version.
11 *
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
15 * more details.
16 *
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/>.
19 */
20#include "mainwindow.h"
21
22#include <QTreeView>
23#include <QFile>
24#include <QNetworkProxy>
25#include <QNetworkAccessManager>
26#include <QNetworkReply>
27
28#include "sqlengine.h"
29
30#include "track.h"
31#include "eventmodel.h"
32#include "delegate.h"
33
34#include "conference.h"
35
36#include <QDialog>
37#include <QMessageBox>
38
39#include "ui_about.h"
40#include "eventdialog.h"
41#include "daynavigatorwidget.h"
42#include "settingsdialog.h"
43#include "conferenceeditor.h"
44#include "schedulexmlparser.h"
45#include "errormessage.h"
46
47#include "tabcontainer.h"
48#include "appsettings.h"
49
50const QString PROXY_USERNAME;
51const QString PROXY_PASSWD;
52
53MainWindow::MainWindow(int aEventId, QWidget *aParent): QMainWindow(aParent) {
54    setupUi(this);
55
56    // Open database
57    sqlEngine = new SqlEngine(this);
58    searchTabContainer->setSqlEngine(sqlEngine);
59    connect(sqlEngine, SIGNAL(dbError(QString)), this, SLOT(showError(QString)));
60    sqlEngine->open();
61    sqlEngine->createOrUpdateDbSchema();
62
63    conferenceModel = new ConferenceModel(this);
64    mXmlParser = new ScheduleXmlParser(sqlEngine, this);
65    mNetworkAccessManager = new QNetworkAccessManager(this);
66
67    saved_title = windowTitle();
68
69#ifdef N810
70    tabWidget->setTabText(1,"Favs");
71    //tabWidget->setTabText(2,"Day");
72#endif
73
74    // first time run aplication: -> let's have it direct connection in this case
75    if(!AppSettings::contains("proxyIsDirectConnection"))
76        AppSettings::setDirectConnection(true);
77
78    /*
79    if(AppSettings::isDirectConnection())
80    {
81        qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
82    }
83    */
84    QNetworkProxy proxy(
85            AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
86            AppSettings::proxyAddress(),
87            AppSettings::proxyPort(),
88            PROXY_USERNAME,
89            PROXY_PASSWD);
90    QNetworkProxy::setApplicationProxy(proxy);
91
92    // event details have changed
93    connect(dayTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
94    connect(favsTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
95    connect(tracksTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
96    connect(roomsTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
97    connect(searchTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
98
99    // date has changed
100    connect(dayNavigator, SIGNAL(dateChanged(QDate)), dayTabContainer, SLOT(redisplayDate(QDate)));
101    connect(dayNavigator, SIGNAL(dateChanged(QDate)), favsTabContainer, SLOT(redisplayDate(QDate)));
102    connect(dayNavigator, SIGNAL(dateChanged(QDate)), tracksTabContainer, SLOT(redisplayDate(QDate)));
103    connect(dayNavigator, SIGNAL(dateChanged(QDate)), roomsTabContainer, SLOT(redisplayDate(QDate)));
104    connect(dayNavigator, SIGNAL(dateChanged(QDate)), searchTabContainer, SLOT(redisplayDate(QDate)));
105
106    // search result has changed
107    connect(searchTabContainer, SIGNAL(searchResultChanged()), SLOT(onSearchResultChanged()));
108
109
110    useConference(Conference::activeConference());
111    // optimization, see useConference() code
112    try {
113        initTabs();
114    } catch (const OrmException& e) {
115        qDebug() << "OrmException:" << e.text();
116        clearTabs();
117    }
118
119    // open dialog for given Event ID
120    // this is used in case Alarm Dialog request application to start
121    if(aEventId)
122    {
123        try
124        {
125            EventDialog dialog(aEventId,this);
126            dialog.exec();
127        }
128        catch(OrmNoObjectException&) {} // just start application
129        catch(...) {} // just start application
130    }
131
132    connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
133
134    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
135    connect(mXmlParser, SIGNAL(parsingScheduleEnd(int)), conferenceModel, SLOT(newConferenceEnd(int)));
136}
137
138void MainWindow::on_aboutAction_triggered()
139{
140    QDialog dialog(this);
141    Ui::AboutDialog ui;
142    ui.setupUi(&dialog);
143    ui.labDescription->setText(ui.labDescription->text().arg(qApp->applicationVersion()));
144#ifdef N810
145    dialog.setFixedWidth(width());
146#endif
147    dialog.exec();
148}
149
150
151void MainWindow::on_reloadAction_triggered() {
152    int confId = Conference::activeConference();
153    if (confId== -1) return;
154    Conference active = Conference::getById(confId);
155    if (active.url().isEmpty()) return;
156    importFromNetwork(active.url(), confId);
157    setEnabled(false);
158}
159
160
161void MainWindow::on_nowAction_triggered() {
162    int confId = Conference::activeConference();
163    if (confId== -1) return;
164    dayNavigator->setCurDate(QDate::currentDate());
165    dayTabContainer->expandTimeGroup(QTime::currentTime(), confId);
166}
167
168
169void MainWindow::on_searchAction_triggered() {
170    if (tabWidget->currentWidget() == searchTab)
171        searchTabContainer->showSearchDialog(!searchTabContainer->searchDialogIsVisible());
172    else {
173        tabWidget->setCurrentWidget(searchTab);
174        searchTabContainer->showSearchDialog();
175    }
176}
177
178
179void MainWindow::on_expandAllAction_triggered() {
180    if (tabWidget->currentWidget() == favouritesTab) favsTabContainer->treeView->expandAll();
181    if (tabWidget->currentWidget() == dayViewTab) dayTabContainer->treeView->expandAll();
182    if (tabWidget->currentWidget() == tracksTab) tracksTabContainer->treeView->expandAll();
183    if (tabWidget->currentWidget() == roomsTab) roomsTabContainer->treeView->expandAll();
184    if (tabWidget->currentWidget() == searchTab) searchTabContainer->treeView->expandAll();
185}
186
187
188void MainWindow::on_collapseAllAction_triggered() {
189    if (tabWidget->currentWidget() == favouritesTab) favsTabContainer->treeView->collapseAll();
190    if (tabWidget->currentWidget() == dayViewTab) dayTabContainer->treeView->collapseAll();
191    if (tabWidget->currentWidget() == tracksTab) tracksTabContainer->treeView->collapseAll();
192    if (tabWidget->currentWidget() == roomsTab) roomsTabContainer->treeView->collapseAll();
193    if (tabWidget->currentWidget() == searchTab) searchTabContainer->treeView->collapseAll();
194}
195
196
197void MainWindow::onEventChanged(int aEventId, bool favouriteChanged) {
198    dayTabContainer->redisplayEvent(aEventId);
199    if (favouriteChanged) favsTabContainer->redisplayDate(dayNavigator->curDate());
200    else favsTabContainer->redisplayEvent(aEventId);
201    tracksTabContainer->redisplayEvent(aEventId);
202    roomsTabContainer->redisplayEvent(aEventId);
203    searchTabContainer->redisplayEvent(aEventId);
204}
205
206
207void MainWindow::onSearchResultChanged() {
208    // Are results found on the current date?
209    QDate date = dayNavigator->curDate();
210    int count = searchTabContainer->searchResultCount(date);
211    if (count > 0) {searchTabContainer->redisplayDate(date); return;}
212
213    // Are results found in the future?
214    for (date = date.addDays(1); date <= dayNavigator->endDate(); date = date.addDays(1)) {
215        int count = searchTabContainer->searchResultCount(date);
216        if (count > 0) {dayNavigator->setCurDate(date); return;}
217    }
218
219    // Are results found in the past?
220    for (date = dayNavigator->startDate(); date < dayNavigator->curDate(); date = date.addDays(1)) {
221        int count = searchTabContainer->searchResultCount(date);
222        if (count > 0) {dayNavigator->setCurDate(date); return;}
223    }
224    // No results were found
225    searchTabContainer->redisplayDate(dayNavigator->curDate());
226}
227
228
229void MainWindow::useConference(int id)
230{
231    if (id == -1)  // in case no conference is active
232    {
233        unsetConference();
234        return;
235    }
236    try {
237        Conference::getById(Conference::activeConference()).update("active",0);
238        Conference new_active = Conference::getById(id);
239        new_active.update("active",1);
240
241        // looks like it does not work at n900
242        setWindowTitle(new_active.title());
243
244        // optimization.
245        // dont run initTabs() here
246        // it takes much CPU, making travelling between conferences in ConferenceEditor longer
247        // and is not seen in maemo WM anyway
248        // instead run it explicitly
249        // 1. at startup
250        // 2. when ConferenceEditor finished
251        // dont forget to protect the calls by try-catch!
252
253        // just in case, clear conference selection instead
254        clearTabs();
255
256        // end of optimization
257        // initTabs();
258    } catch (OrmException& e) {
259        // cannon set an active conference
260        unsetConference();   // TODO: as no active conference is now correctly managed this should be handled as a fatal error
261        return;
262    }
263
264}
265
266void MainWindow::initTabs()
267{
268    int confId = Conference::activeConference();
269    if (confId != -1)   // only init tabs if a conference is active
270    {
271        Conference active = Conference::getById(confId);
272        QDate startDate = active.start();
273        QDate endDate = active.end();
274
275        // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
276        dayNavigator->setDates(startDate, endDate);
277    }
278}
279
280void MainWindow::clearTabs()
281{
282    dayTabContainer->clearModel();
283    tracksTabContainer->clearModel();
284    roomsTabContainer->clearModel();
285    favsTabContainer->clearModel();
286    searchTabContainer->clearModel();
287}
288
289void MainWindow::unsetConference()
290{
291    clearTabs();
292    dayNavigator->unsetDates();
293    setWindowTitle(saved_title);
294}
295
296
297void MainWindow::showError(const QString& message) {
298    error_message(message);
299}
300
301
302void MainWindow::on_settingsAction_triggered()
303{
304    SettingsDialog dialog;
305    dialog.loadDialogData();
306    if (dialog.exec() == QDialog::Accepted) {
307        dialog.saveDialogData();
308        QNetworkProxy proxy(
309                AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
310                AppSettings::proxyAddress(),
311                AppSettings::proxyPort(),
312                PROXY_USERNAME,
313                PROXY_PASSWD);
314        QNetworkProxy::setApplicationProxy(proxy);
315    }
316}
317
318/** Create and run ConferenceEditor dialog, making required connections for it.
319
320This method manages, which classes actually perform changes in conference list.
321
322There are several classes that modify the conferences:
323this:
324 deletion and URL update.
325this, mXmlParser and mNetworkAccessManager:
326 addition and refresh.
327*/
328void MainWindow::on_conferencesAction_triggered()
329{
330    ConferenceEditor dialog(conferenceModel, this);
331
332    connect(&dialog, SIGNAL(haveConferenceUrl(const QString&, int)), SLOT(importFromNetwork(const QString&, int)));
333    connect(&dialog, SIGNAL(haveConferenceFile(const QString&, int)), SLOT(importFromFile(const QString&, int)));
334    connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
335    connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
336                    SLOT(changeConferenceUrl(int, const QString&)));
337
338    connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
339    connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
340
341    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
342    connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
343    connect(mXmlParser, SIGNAL(parsingScheduleEnd(int)), &dialog, SLOT(importFinished(int)));
344
345    connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
346
347    dialog.exec();
348
349    // optimization, see useConference() code
350    try {
351        initTabs();
352    } catch (OrmException) {
353        clearTabs();
354    }
355}
356
357void MainWindow::networkQueryFinished(QNetworkReply *aReply) {
358    if (aReply->error() != QNetworkReply::NoError) {
359        error_message(QString("Error occured during download: ") + aReply->errorString());
360    } else {
361        QUrl redirectUrl = aReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
362        if (!redirectUrl.isEmpty()) {
363            if (redirectUrl != aReply->request().url()) {
364                importFromNetwork(redirectUrl.toString(), aReply->request().attribute(QNetworkRequest::User).toInt());
365                return; // don't enable controls
366            } else {
367                error_message(QString("Error: Cyclic redirection from %1 to itself.").arg(redirectUrl.toString()));
368            }
369        } else {
370            importData(aReply->readAll(), aReply->url().toEncoded(), aReply->request().attribute(QNetworkRequest::User).toInt());
371        }
372    }
373    setEnabled(true);
374}
375
376void MainWindow::importData(const QByteArray &aData, const QString& url, int conferenceId)
377{
378    mXmlParser->parseData(aData, url, conferenceId);
379}
380
381void MainWindow::importFromNetwork(const QString& url, int conferenceId)
382{
383    QNetworkRequest request;
384    request.setUrl(QUrl(url));
385    request.setAttribute(QNetworkRequest::User, conferenceId);
386
387    mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
388    mNetworkAccessManager->get(request);
389}
390
391void MainWindow::importFromFile(const QString& filename, int conferenceId)
392{
393    QFile file(filename);
394    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {   
395        static const QString format("Cannot read \"%1\": error %2");
396        error_message(format.arg(filename, QString::number(file.error())));
397    }
398
399    importData(file.readAll(), "", conferenceId);
400}
401
402
403void MainWindow::removeConference(int id) {
404    sqlEngine->deleteConference(id);
405    conferenceModel->conferenceRemoved();
406    emit conferenceRemoved();
407}
408
409
410void MainWindow::changeConferenceUrl(int id, const QString& url) {
411    Conference::getById(id).setUrl(url);
412}
413
Note: See TracBrowser for help on using the repository browser.