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

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

The search result is now synced with the daynavigator.
When the search result is not on the current date, the date is changed.

  • Property mode set to 100644
File size: 11.9 KB
Line 
1/*
2 * Copyright (C) 2010 Ixonos Plc.
3 * Copyright (C) 2011 Philipp Spitzer, gregor herrmann
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)
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    /*
73    if(AppSettings::isDirectConnection())
74    {
75        qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
76    }
77    */
78    QNetworkProxy proxy(
79            AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
80            AppSettings::proxyAddress(),
81            AppSettings::proxyPort(),
82            PROXY_USERNAME,
83            PROXY_PASSWD);
84    QNetworkProxy::setApplicationProxy(proxy);
85
86    // event details have changed
87    connect(dayTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
88    connect(favsTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
89    connect(tracksTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
90    connect(roomsTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
91    connect(searchTabContainer, SIGNAL(eventChanged(int,bool)), SLOT(onEventChanged(int,bool)));
92
93    // date has changed
94    connect(dayNavigator, SIGNAL(dateChanged(QDate)), dayTabContainer, SLOT(redisplayDate(QDate)));
95    connect(dayNavigator, SIGNAL(dateChanged(QDate)), favsTabContainer, SLOT(redisplayDate(QDate)));
96    connect(dayNavigator, SIGNAL(dateChanged(QDate)), tracksTabContainer, SLOT(redisplayDate(QDate)));
97    connect(dayNavigator, SIGNAL(dateChanged(QDate)), roomsTabContainer, SLOT(redisplayDate(QDate)));
98    connect(dayNavigator, SIGNAL(dateChanged(QDate)), searchTabContainer, SLOT(redisplayDate(QDate)));
99
100    // search result has changed
101    connect(searchTabContainer, SIGNAL(searchResultChanged()), SLOT(onSearchResultChanged()));
102
103
104    useConference(Conference::activeConference());
105    // optimization, see useConference() code
106    try {
107        initTabs();
108    } catch (const OrmException& e) {
109        qDebug() << "OrmException:" << e.text();
110        clearTabs();
111    }
112
113    // open dialog for given Event ID
114    // this is used in case Alarm Dialog request application to start
115    if(aEventId)
116    {
117        try
118        {
119            EventDialog dialog(aEventId,this);
120            dialog.exec();
121        }
122        catch(OrmNoObjectException&) {} // just start application
123        catch(...) {} // just start application
124    }
125
126    connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
127
128    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
129    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
130}
131
132void MainWindow::on_aboutAction_triggered()
133{
134    QDialog dialog(this);
135    Ui::AboutDialog ui;
136    ui.setupUi(&dialog);
137    ui.labDescription->setText(ui.labDescription->text().arg(qApp->applicationVersion()));
138#ifdef N810
139    dialog.setFixedWidth(width());
140#endif
141    dialog.exec();
142}
143
144
145void MainWindow::on_reloadAction_triggered() {
146    int confId = Conference::activeConference();
147    if (confId== -1) return;
148    Conference active = Conference::getById(confId);
149    if (active.url().isEmpty()) return;
150    importFromNetwork(active.url());
151    setEnabled(false);
152}
153
154
155void MainWindow::on_nowAction_triggered() {
156    int confId = Conference::activeConference();
157    if (confId== -1) return;
158    dayNavigator->setCurDate(QDate::currentDate());
159    dayTabContainer->expandTimeGroup(QTime::currentTime(), confId);
160}
161
162
163void MainWindow::on_searchAction_triggered() {
164    searchTabContainer->showSearchDialog();
165    tabWidget->setCurrentWidget(searchTab);
166}
167
168
169void MainWindow::onEventChanged(int aEventId, bool favouriteChanged) {
170    dayTabContainer->redisplayEvent(aEventId);
171    if (favouriteChanged) favsTabContainer->redisplayDate(dayNavigator->curDate());
172    else favsTabContainer->redisplayEvent(aEventId);
173    tracksTabContainer->redisplayEvent(aEventId);
174    roomsTabContainer->redisplayEvent(aEventId);
175    searchTabContainer->redisplayEvent(aEventId);
176}
177
178
179void MainWindow::onSearchResultChanged() {
180    // Are results found on the current date?
181    QDate date = dayNavigator->curDate();
182    int count = searchTabContainer->searchResultCount(date);
183    if (count > 0) {searchTabContainer->redisplayDate(date); return;}
184
185    // Are results found in the future?
186    for (date = date.addDays(1); date <= dayNavigator->endDate(); date = date.addDays(1)) {
187        int count = searchTabContainer->searchResultCount(date);
188        if (count > 0) {dayNavigator->setCurDate(date); return;}
189    }
190
191    // Are results found in the past?
192    for (date = dayNavigator->startDate(); date < dayNavigator->curDate(); date = date.addDays(1)) {
193        int count = searchTabContainer->searchResultCount(date);
194        if (count > 0) {dayNavigator->setCurDate(date); return;}
195    }
196    // No results were found
197    searchTabContainer->redisplayDate(dayNavigator->curDate());
198}
199
200
201void MainWindow::useConference(int id)
202{
203    if (id == -1)  // in case no conference is active
204    {
205        unsetConference();
206        return;
207    }
208    try {
209        Conference::getById(Conference::activeConference()).update("active",0);
210        Conference new_active = Conference::getById(id);
211        new_active.update("active",1);
212
213        // looks like it does not work at n900
214        setWindowTitle(new_active.title());
215
216        // optimization.
217        // dont run initTabs() here
218        // it takes much CPU, making travelling between conferences in ConferenceEditor longer
219        // and is not seen in maemo WM anyway
220        // instead run it explicitly
221        // 1. at startup
222        // 2. when ConferenceEditor finished
223        // dont forget to protect the calls by try-catch!
224
225        // just in case, clear conference selection instead
226        clearTabs();
227
228        // end of optimization
229        // initTabs();
230    } catch (OrmException& e) {
231        // cannon set an active conference
232        unsetConference();   // TODO: as no active conference is now correctly managed this should be handled as a fatal error
233        return;
234    }
235
236}
237
238void MainWindow::initTabs()
239{
240    int confId = Conference::activeConference();
241    if (confId != -1)   // only init tabs if a conference is active
242    {
243        Conference active = Conference::getById(confId);
244        QDate startDate = active.start();
245        QDate endDate = active.end();
246
247        // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
248        dayNavigator->setDates(startDate, endDate);
249    }
250}
251
252void MainWindow::clearTabs()
253{
254    dayTabContainer->clearModel();
255    tracksTabContainer->clearModel();
256    roomsTabContainer->clearModel();
257    favsTabContainer->clearModel();
258    searchTabContainer->clearModel();
259}
260
261void MainWindow::unsetConference()
262{
263    clearTabs();
264    dayNavigator->unsetDates();
265    setWindowTitle(saved_title);
266}
267
268void MainWindow::on_settingsAction_triggered()
269{
270    SettingsDialog dialog;
271    dialog.loadDialogData();
272    if (dialog.exec() == QDialog::Accepted) {
273        dialog.saveDialogData();
274        QNetworkProxy proxy(
275                AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
276                AppSettings::proxyAddress(),
277                AppSettings::proxyPort(),
278                PROXY_USERNAME,
279                PROXY_PASSWD);
280        QNetworkProxy::setApplicationProxy(proxy);
281    }
282}
283
284/** Create and run ConferenceEditor dialog, making required connections for it.
285
286This method manages, which classes actually perform changes in conference list.
287
288There are several classes that modify the conferences:
289this:
290 deletion and URL update.
291this, mXmlParser and mNetworkAccessManager:
292 addition and refresh.
293*/
294void MainWindow::on_conferencesAction_triggered()
295{
296    ConferenceEditor dialog(conferenceModel, this);
297
298    connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
299    connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
300    connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
301    connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
302                    SLOT(changeConferenceUrl(int, const QString&)));
303
304    connect(&dialog, SIGNAL(haveConferenceSelected(int)), SLOT(useConference(int)));
305    connect(&dialog, SIGNAL(noneConferenceSelected()), SLOT(unsetConference()));
306
307    connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
308    connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
309    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
310
311    connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
312
313    dialog.exec();
314
315    // optimization, see useConference() code
316    try {
317        initTabs();
318    } catch (OrmException) {
319        clearTabs();
320    }
321}
322
323void MainWindow::networkQueryFinished(QNetworkReply *aReply)
324{
325    if ( aReply->error() != QNetworkReply::NoError )
326    {
327        error_message(QString("Error occured during download: ") + aReply->errorString());
328    }
329    else
330    {
331        importData(aReply->readAll(), aReply->url().toEncoded());
332    }
333    setEnabled(true);
334}
335
336void MainWindow::importData(const QByteArray &aData, const QString& url)
337{
338    mXmlParser->parseData(aData, url);
339}
340
341void MainWindow::importFromNetwork(const QString& url)
342{
343    QNetworkRequest request;
344    request.setUrl(QUrl(url));
345
346    mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
347    mNetworkAccessManager->get(request);
348}
349
350void MainWindow::importFromFile(const QString& filename)
351{
352    QFile file(filename);
353    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {   
354        static const QString format("Cannot read \"%1\": error %2");
355        error_message(format.arg(filename, QString::number(file.error())));
356    }
357
358    importData(file.readAll(), "");
359}
360
361void MainWindow::removeConference(int id)
362{
363    Conference::deleteConference(id);
364    conferenceModel->conferenceRemoved();
365
366    emit conferenceRemoved();
367}
368
369void MainWindow::changeConferenceUrl(int id, const QString& url)
370{
371    Conference::getById(id).setUrl(url);
372}
373
Note: See TracBrowser for help on using the repository browser.