source: src/gui/mainwindow.cpp @ c8c414f

qt5
Last change on this file since c8c414f was c8c414f, checked in by kirilma <kirilma@…>, 12 years ago

optimization

  • Property mode set to 100644
File size: 14.1 KB
Line 
1/*
2 * Copyright (C) 2010 Ixonos Plc.
3 *
4 * This file is part of fosdem-schedule.
5 *
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)
9 * any later version.
10 *
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
14 * more details.
15 *
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/>.
18 */
19#include "mainwindow.h"
20
21#include <QTreeView>
22#include <QFile>
23#include <QNetworkProxy>
24#include <QNetworkAccessManager>
25#include <QNetworkReply>
26
27#include <sqlengine.h>
28
29#include <track.h>
30#include <eventmodel.h>
31#include <delegate.h>
32
33#include <conference.h>
34
35#include <QDialog>
36#include <QMessageBox>
37
38#include "ui_about.h"
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"
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)
54    : QMainWindow(aParent)
55    , conferenceModel(new ConferenceModel(this))
56    , mXmlParser(new ScheduleXmlParser(this))
57    , mNetworkAccessManager(new QNetworkAccessManager(this))
58{
59    setupUi(this);
60
61    saved_title = windowTitle();
62
63#ifdef N810
64    tabWidget->setTabText(1,"Favs");
65    //tabWidget->setTabText(2,"Day");
66#endif
67
68    // first time run aplication: -> let's have it direct connection in this case
69    if(!AppSettings::contains("proxyIsDirectConnection"))
70        AppSettings::setDirectConnection(true);
71
72    if(AppSettings::isDirectConnection())
73    {
74        qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
75    }
76    QNetworkProxy proxy(
77            AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
78            AppSettings::proxyAddress(),
79            AppSettings::proxyPort(),
80            PROXY_USERNAME,
81            PROXY_PASSWD);
82    QNetworkProxy::setApplicationProxy(proxy);
83
84    #if 0
85    // list of conferences must be maintained by ConferenceEditor
86    // here must be one of the signals from the closing ConferenceEditor (or model):
87    // selectedConf(conference), noConf()
88    connect(importScheduleWidget, SIGNAL(scheduleImported(int)), SLOT(scheduleImported(int)));
89    connect(importScheduleWidget, SIGNAL(scheduleDeleted(const QString&)), SLOT(scheduleDeleted(const QString&)));
90    #endif
91
92    // event details have changed
93    connect(dayTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
94    connect(favsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
95    connect(tracksTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
96    connect(roomsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
97    connect(nowTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
98    connect(searchTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
99
100    // event conference map button clicked
101    #if 0
102    // TODO: think about it when return to maps
103    connect(showMapButton, SIGNAL(clicked()), SLOT(conferenceMapClicked()));
104    #endif
105
106    connect(aboutAction, SIGNAL(triggered()), SLOT(aboutApp()));
107    connect(settingsAction, SIGNAL(triggered()), SLOT(setup()));
108    connect(conferencesAction, SIGNAL(triggered()), SLOT(showConferences()));
109
110    useConference(Conference::activeConference());
111    // optimization, see useConference() code
112    try {
113        initTabs();
114    } catch (OrmException) {
115        clearTabs();
116    }
117
118    #if 0
119    // TODO: remove GUI
120    // initialisation of model and pick active conference from there and call conferenceChanged()
121    // selectConference->setDuplicatesEnabled(false);
122    int confCount = Conference::getAll().count();
123    if(confCount)
124    {
125        initTabs();
126        // fillAndShowConferenceHeader();
127        setWindowTitle(Conference::getById(confId).title());
128
129        QList<Conference> confs = Conference::getAll();
130        QListIterator<Conference> i(confs);
131        while(i.hasNext())
132        {
133            Conference conf = i.next();
134            // TODO: remove GUI
135            // selectConference->addItem(conf.title(),conf.id());
136        }
137        // TODO: remove GUI
138        // int idx = selectConference->findText(Conference::getById(Conference::activeConference()).title());
139        // selectConference->setCurrentIndex(idx);
140        // connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
141        // conferenceChanged(idx);
142    }
143    else
144    {
145        // TODO: remove GUI
146        // conferenceHeader->hide();
147        // selectConferenceWidget->hide();
148        // // go to the 'conferenceTab', so the user can import the schedule
149        // tabWidget->setCurrentIndex(6); // 6 - conference tab
150    }
151    #endif
152
153    // open dialog for given Event ID
154    // this is used in case Alarm Dialog request application to start
155    if(aEventId)
156    {
157        try
158        {
159            EventDialog dialog(aEventId,this);
160            dialog.exec();
161        }
162        catch(OrmNoObjectException&) {} // just start application
163        catch(...) {} // just start application
164    }
165
166    connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
167
168    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
169    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
170}
171
172void MainWindow::scheduleImported(int aConfId)
173{
174    Q_UNUSED(aConfId);
175
176    // TODO: this all goes to ConferenceEditor and model of conferences
177    #if 0
178
179    Conference conf = Conference::getById(aConfId);
180    if( selectConference->findText(conf.title()) < 0 ) // item doesn't exist
181    {
182        disconnect(selectConference, SIGNAL(currentIndexChanged(int)), this, SLOT(conferenceChanged(int)));
183        selectConference->addItem(conf.title(),conf.id());
184        connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
185    }
186    int confCount = Conference::getAll().count();
187    if(confCount)
188    {
189        int idx = selectConference->findText(conf.title());
190        selectConference->setCurrentIndex(idx);
191
192        selectConferenceWidget->show();
193
194        conferenceChanged(idx);
195    }
196    #endif
197}
198
199void MainWindow::scheduleDeleted(const QString& title)
200{
201    Q_UNUSED(title);
202    // TODO: this all goes to ConferenceEditor and model of conferences
203    #if 0
204    int idx = selectConference->findText(title);
205
206    if (idx == -1) {
207        // should not happen
208        qWarning() << __PRETTY_FUNCTION__ << "removed non-existent item:" << title;
209        // this happens when you remove the only conference (the list is not ptoperly inited in this case)
210        // now make sure that conferencet
211        if (selectConference->count() > 0) {
212            selectConference->setCurrentIndex(0);
213            conferenceChanged(0);
214        } else {
215            conferenceChanged(-1);
216        }
217    } else {
218        // will it signal "changed"?
219        selectConference->removeItem(idx);
220    }
221    #endif
222}
223
224void MainWindow::aboutApp()
225{
226    QDialog dialog(this);
227    Ui::AboutDialog ui;
228    ui.setupUi(&dialog);
229#ifdef N810
230    dialog.setFixedWidth(width());
231#endif
232    dialog.exec();
233}
234
235void MainWindow::conferenceMapClicked()
236{
237    QString mapPath = QString(":/maps/campus.png");
238    if(!QFile::exists(mapPath))
239        mapPath = QString(":/maps/rooms/not-available.png");
240
241    QString roomName;
242
243    QPixmap map(mapPath);
244    MapWindow window(map,roomName,this);
245    window.exec();
246}
247
248void MainWindow::eventHasChanged(int aEventId, bool aReloadModel)
249{
250    dayTabContainer->updateTreeViewModel(aEventId);
251    favsTabContainer->updateTreeViewModel(aEventId,aReloadModel);
252    tracksTabContainer->updateTreeViewModel(aEventId);
253    nowTabContainer->updateTreeViewModel(aEventId);
254    roomsTabContainer->updateTreeViewModel(aEventId);
255    searchTabContainer->updateTreeViewModel(aEventId);
256}
257
258void MainWindow::useConference(int id)
259{
260    try {
261        Conference::getById(Conference::activeConference()).update("active",0);
262        Conference new_active = Conference::getById(id);
263        new_active.update("active",1);
264
265        // looks like it does not work at n900
266        setWindowTitle(new_active.title());
267
268        // optimization.
269        // dont run initTabs() here
270        // it takes much CPU, making travelling between conferences in ConferenceEditor longer
271        // and is not seen in maemo WM anyway
272        // instead run it explicitly where needed
273        // dont forget to protect the calls by try-catch!
274
275        // just in case, clear conference selection instead
276        clearTabs();
277
278        // end of optimization
279        // initTabs();
280    } catch (OrmException& e) {
281        // cannon set an active conference
282        unsetConference();
283        return;
284    }
285
286}
287
288void MainWindow::initTabs()
289{
290    int confId = Conference::activeConference();
291    Conference active = Conference::getById(confId);
292    QDate startDate = active.start();
293    QDate endDate = active.end();
294
295    // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
296    dayTabContainer->setDates(startDate, endDate);
297    tracksTabContainer->setDates(startDate, endDate);
298    roomsTabContainer->setDates(startDate, endDate);
299    favsTabContainer->setDates(startDate, endDate);
300    searchTabContainer->setDates(startDate, endDate);
301    searchTabContainer->searchAgainClicked();
302    nowTabContainer->updateTreeView(QDate::currentDate());
303}
304
305void MainWindow::clearTabs()
306{
307    dayTabContainer->clearModel();
308    tracksTabContainer->clearModel();
309    roomsTabContainer->clearModel();
310    favsTabContainer->clearModel();
311    searchTabContainer->clearModel();
312    searchTabContainer->searchAgainClicked();
313    nowTabContainer->clearModel();
314}
315
316void MainWindow::unsetConference()
317{
318    clearTabs();
319    setWindowTitle(saved_title);
320}
321
322void MainWindow::setup()
323{
324    SettingsDialog dialog;
325    dialog.exec();
326
327    qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
328    QNetworkProxy proxy(
329            AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
330            AppSettings::proxyAddress(),
331            AppSettings::proxyPort(),
332            PROXY_USERNAME,
333            PROXY_PASSWD);
334    QNetworkProxy::setApplicationProxy(proxy);
335}
336
337/** Create and run ConferenceEditor dialog, making required connections for it.
338
339This method manages, which classes actually perform changes in conference list.
340
341There are several classes that modify the conferences:
342this:
343 deletion and URL update.
344this, mXmlParser and mNetworkAccessManager:
345 addition and refresh.
346*/
347void MainWindow::showConferences()
348{
349    ConferenceEditor dialog(conferenceModel, this);
350
351    // TODO: connect signals about progress of network and parsing
352
353    connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
354    connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
355    connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
356    connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
357                    SLOT(changeConferenceUrl(int, const QString&)));
358
359    connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
360    connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
361
362    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
363    connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
364    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
365
366    connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
367
368    dialog.exec();
369
370    // optimization, see useConference() code
371    try {
372        initTabs();
373    } catch (OrmException) {
374        clearTabs();
375    }
376}
377
378void MainWindow::networkQueryFinished(QNetworkReply *aReply)
379{
380    if ( aReply->error() != QNetworkReply::NoError )
381    {
382        error_message(QString("Error occured during download: ") + aReply->errorString());
383    }
384    else
385    {
386        qDebug() << __PRETTY_FUNCTION__ << ": have data";
387        importData(aReply->readAll(), aReply->url().toEncoded());
388    }
389}
390
391void MainWindow::importData(const QByteArray &aData, const QString& url)
392{
393    // TODO: remove GUI
394    // instead send signals to the child dialog
395    #if 0
396    browse->hide();
397    online->hide();
398    progressBar->show();
399    // proxySettings->hide();
400    #endif
401
402    int confId = mXmlParser->parseData(aData, url);
403
404    #if 0
405    progressBar->hide();
406    browse->show();
407    online->show();
408    // proxySettings->show();
409    importScheduleLabel->setText("Schedule:");
410
411    #endif
412    if (confId > 0) {
413        emit(scheduleImported(confId));
414    }
415}
416
417void MainWindow::importFromNetwork(const QString& url)
418{
419    qDebug() << __PRETTY_FUNCTION__;
420    QNetworkRequest request;
421    request.setUrl(QUrl(url));
422
423    mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
424    mNetworkAccessManager->get(request);
425}
426
427void MainWindow::importFromFile(const QString& filename)
428{
429    qDebug() << __PRETTY_FUNCTION__;
430    QFile file(filename);
431    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {   
432        static const QString format("Cannot read \"%1\": error %2");
433        error_message(format.arg(filename, QString::number(file.error())));
434    }
435
436    importData(file.readAll(), "");
437}
438
439void MainWindow::removeConference(int id)
440{
441    Conference::deleteConference(id);
442    conferenceModel->conferenceRemoved();
443
444    emit conferenceRemoved();
445}
446
447void MainWindow::changeConferenceUrl(int id, const QString& url)
448{
449    Conference::getById(id).setUrl(url);
450}
451
Note: See TracBrowser for help on using the repository browser.