source: src/gui/mainwindow.cpp @ b431d47

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

reworked UI for conference editing

underlying representation of conference list is also changed

  • Property mode set to 100644
File size: 13.4 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
112    #if 0
113    // TODO: remove GUI
114    // initialisation of model and pick active conference from there and call conferenceChanged()
115    // selectConference->setDuplicatesEnabled(false);
116    int confCount = Conference::getAll().count();
117    if(confCount)
118    {
119        initTabs();
120        // fillAndShowConferenceHeader();
121        setWindowTitle(Conference::getById(confId).title());
122
123        QList<Conference> confs = Conference::getAll();
124        QListIterator<Conference> i(confs);
125        while(i.hasNext())
126        {
127            Conference conf = i.next();
128            // TODO: remove GUI
129            // selectConference->addItem(conf.title(),conf.id());
130        }
131        // TODO: remove GUI
132        // int idx = selectConference->findText(Conference::getById(Conference::activeConference()).title());
133        // selectConference->setCurrentIndex(idx);
134        // connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
135        // conferenceChanged(idx);
136    }
137    else
138    {
139        // TODO: remove GUI
140        // conferenceHeader->hide();
141        // selectConferenceWidget->hide();
142        // // go to the 'conferenceTab', so the user can import the schedule
143        // tabWidget->setCurrentIndex(6); // 6 - conference tab
144    }
145    #endif
146
147    // open dialog for given Event ID
148    // this is used in case Alarm Dialog request application to start
149    if(aEventId)
150    {
151        try
152        {
153            EventDialog dialog(aEventId,this);
154            dialog.exec();
155        }
156        catch(OrmNoObjectException&) {} // just start application
157        catch(...) {} // just start application
158    }
159
160    connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
161
162    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
163    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
164}
165
166void MainWindow::scheduleImported(int aConfId)
167{
168    Q_UNUSED(aConfId);
169
170    // TODO: this all goes to ConferenceEditor and model of conferences
171    #if 0
172
173    Conference conf = Conference::getById(aConfId);
174    if( selectConference->findText(conf.title()) < 0 ) // item doesn't exist
175    {
176        disconnect(selectConference, SIGNAL(currentIndexChanged(int)), this, SLOT(conferenceChanged(int)));
177        selectConference->addItem(conf.title(),conf.id());
178        connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
179    }
180    int confCount = Conference::getAll().count();
181    if(confCount)
182    {
183        int idx = selectConference->findText(conf.title());
184        selectConference->setCurrentIndex(idx);
185
186        selectConferenceWidget->show();
187
188        conferenceChanged(idx);
189    }
190    #endif
191}
192
193void MainWindow::scheduleDeleted(const QString& title)
194{
195    Q_UNUSED(title);
196    // TODO: this all goes to ConferenceEditor and model of conferences
197    #if 0
198    int idx = selectConference->findText(title);
199
200    if (idx == -1) {
201        // should not happen
202        qWarning() << __PRETTY_FUNCTION__ << "removed non-existent item:" << title;
203        // this happens when you remove the only conference (the list is not ptoperly inited in this case)
204        // now make sure that conferencet
205        if (selectConference->count() > 0) {
206            selectConference->setCurrentIndex(0);
207            conferenceChanged(0);
208        } else {
209            conferenceChanged(-1);
210        }
211    } else {
212        // will it signal "changed"?
213        selectConference->removeItem(idx);
214    }
215    #endif
216}
217
218void MainWindow::aboutApp()
219{
220    QDialog dialog(this);
221    Ui::AboutDialog ui;
222    ui.setupUi(&dialog);
223#ifdef N810
224    dialog.setFixedWidth(width());
225#endif
226    dialog.exec();
227}
228
229void MainWindow::conferenceMapClicked()
230{
231    QString mapPath = QString(":/maps/campus.png");
232    if(!QFile::exists(mapPath))
233        mapPath = QString(":/maps/rooms/not-available.png");
234
235    QString roomName;
236
237    QPixmap map(mapPath);
238    MapWindow window(map,roomName,this);
239    window.exec();
240}
241
242void MainWindow::eventHasChanged(int aEventId, bool aReloadModel)
243{
244    dayTabContainer->updateTreeViewModel(aEventId);
245    favsTabContainer->updateTreeViewModel(aEventId,aReloadModel);
246    tracksTabContainer->updateTreeViewModel(aEventId);
247    nowTabContainer->updateTreeViewModel(aEventId);
248    roomsTabContainer->updateTreeViewModel(aEventId);
249    searchTabContainer->updateTreeViewModel(aEventId);
250}
251
252void MainWindow::useConference(int id)
253{
254    try {
255        Conference::getById(Conference::activeConference()).update("active",0);
256        Conference::getById(id).update("active",1);
257
258        initTabs();
259    } catch (OrmException& e) {
260        // cannon set an active conference
261        unsetConference();
262        return;
263    }
264
265}
266
267void MainWindow::initTabs()
268{
269    int confId = Conference::activeConference();
270    Conference active = Conference::getById(confId);
271    QDate startDate = active.start();
272    QDate endDate = active.end();
273    setWindowTitle(active.title());
274
275    // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
276    dayTabContainer->setDates(startDate, endDate);
277    tracksTabContainer->setDates(startDate, endDate);
278    roomsTabContainer->setDates(startDate, endDate);
279    favsTabContainer->setDates(startDate, endDate);
280    searchTabContainer->setDates(startDate, endDate);
281    searchTabContainer->searchAgainClicked();
282    nowTabContainer->updateTreeView(QDate::currentDate());
283}
284
285void MainWindow::unsetConference()
286{
287    dayTabContainer->clearModel();
288    tracksTabContainer->clearModel();
289    roomsTabContainer->clearModel();
290    favsTabContainer->clearModel();
291    searchTabContainer->clearModel();
292    searchTabContainer->searchAgainClicked();
293    nowTabContainer->clearModel();
294
295    // TODO:  remove
296    // conferenceHeader->hide();
297    setWindowTitle(saved_title);
298}
299
300void MainWindow::setup()
301{
302    SettingsDialog dialog;
303    dialog.exec();
304
305    qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
306    QNetworkProxy proxy(
307            AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
308            AppSettings::proxyAddress(),
309            AppSettings::proxyPort(),
310            PROXY_USERNAME,
311            PROXY_PASSWD);
312    QNetworkProxy::setApplicationProxy(proxy);
313}
314
315/** Create and run ConferenceEditor dialog, making required connections for it.
316
317This method manages, which classes actually perform changes in conference list.
318
319There are several classes that modify the conferences:
320this:
321 deletion and URL update.
322this, mXmlParser and mNetworkAccessManager:
323 addition and refresh.
324*/
325void MainWindow::showConferences()
326{
327    ConferenceEditor dialog(conferenceModel, this);
328
329    // TODO: connect signals about progress of network and parsing
330
331    connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
332    connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
333    connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
334    connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
335                    SLOT(changeConferenceUrl(int, const QString&)));
336
337    connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
338    connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
339
340    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
341    connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
342    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
343
344    connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
345
346    dialog.exec();
347}
348
349void MainWindow::networkQueryFinished(QNetworkReply *aReply)
350{
351    if ( aReply->error() != QNetworkReply::NoError )
352    {
353        error_message(QString("Error occured during download: ") + aReply->errorString());
354    }
355    else
356    {
357        qDebug() << __PRETTY_FUNCTION__ << ": have data";
358        importData(aReply->readAll(), aReply->url().toEncoded());
359    }
360}
361
362void MainWindow::importData(const QByteArray &aData, const QString& url)
363{
364    // TODO: remove GUI
365    // instead send signals to the child dialog
366    #if 0
367    browse->hide();
368    online->hide();
369    progressBar->show();
370    // proxySettings->hide();
371    #endif
372
373    int confId = mXmlParser->parseData(aData, url);
374
375    #if 0
376    progressBar->hide();
377    browse->show();
378    online->show();
379    // proxySettings->show();
380    importScheduleLabel->setText("Schedule:");
381
382    #endif
383    if (confId > 0) {
384        emit(scheduleImported(confId));
385    }
386}
387
388void MainWindow::importFromNetwork(const QString& url)
389{
390    qDebug() << __PRETTY_FUNCTION__;
391    QNetworkRequest request;
392    request.setUrl(QUrl(url));
393
394    mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
395    mNetworkAccessManager->get(request);
396}
397
398void MainWindow::importFromFile(const QString& filename)
399{
400    qDebug() << __PRETTY_FUNCTION__;
401    QFile file(filename);
402    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {   
403        static const QString format("Cannot read \"%1\": error %2");
404        error_message(format.arg(filename, QString::number(file.error())));
405    }
406
407    importData(file.readAll(), "");
408}
409
410void MainWindow::removeConference(int id)
411{
412    Conference::deleteConference(id);
413    conferenceModel->conferenceRemoved();
414
415    emit conferenceRemoved();
416}
417
418void MainWindow::changeConferenceUrl(int id, const QString& url)
419{
420    Conference::getById(id).setUrl(url);
421}
422
Note: See TracBrowser for help on using the repository browser.