fix deletion of last conference
[toast/confclerk.git] / src / gui / mainwindow.cpp
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
25 #include <sqlengine.h>
26
27 #include <track.h>
28 #include <eventmodel.h>
29 #include <delegate.h>
30
31 #include <conference.h>
32
33 #include <QDialog>
34 #include <QMessageBox>
35 #include "ui_about.h"
36 #include <eventdialog.h>
37 #include "daynavigatorwidget.h"
38 #include "importschedulewidget.h"
39 #include "mapwindow.h"
40 #include "settingsdialog.h"
41
42 #include <tabcontainer.h>
43 #include <appsettings.h>
44
45 const QString PROXY_USERNAME;
46 const QString PROXY_PASSWD;
47
48 MainWindow::MainWindow(int aEventId, QWidget *aParent)
49     : QMainWindow(aParent)
50 {
51     setupUi(this);
52
53     saved_title = windowTitle();
54
55 #ifdef N810
56     tabWidget->setTabText(1,"Favs");
57     //tabWidget->setTabText(2,"Day");
58 #endif
59
60     // first time run aplication: -> let's have it direct connection in this case
61     if(!AppSettings::contains("proxyIsDirectConnection"))
62         AppSettings::setDirectConnection(true);
63
64     if(AppSettings::isDirectConnection())
65     {
66         qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
67     }
68     QNetworkProxy proxy(
69             AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
70             AppSettings::proxyAddress(),
71             AppSettings::proxyPort(),
72             PROXY_USERNAME,
73             PROXY_PASSWD);
74     QNetworkProxy::setApplicationProxy(proxy);
75
76     int confId = Conference::activeConference();
77
78     connect(importScheduleWidget, SIGNAL(scheduleImported(int)), SLOT(scheduleImported(int)));
79     connect(importScheduleWidget, SIGNAL(scheduleDeleted(const QString&)), SLOT(scheduleDeleted(const QString&)));
80
81     // event details have changed
82     connect(dayTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
83     connect(favsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
84     connect(tracksTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
85     connect(roomsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
86     connect(nowTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
87     connect(searchTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
88
89     // event conference map button clicked
90     connect(showMapButton, SIGNAL(clicked()), SLOT(conferenceMapClicked()));
91
92     connect(aboutAction, SIGNAL(triggered()), SLOT(aboutApp()));
93     connect(settingsAction, SIGNAL(triggered()), SLOT(setup()));
94
95     selectConference->setDuplicatesEnabled(false);
96     int confCount = Conference::getAll().count();
97     if(confCount)
98     {
99         initTabs();
100         fillAndShowConferenceHeader();
101         setWindowTitle(Conference::getById(confId).title());
102
103         QList<Conference> confs = Conference::getAll();
104         QListIterator<Conference> i(confs);
105         while(i.hasNext())
106         {
107             Conference conf = i.next();
108             selectConference->addItem(conf.title(),conf.id());
109         }
110         int idx = selectConference->findText(Conference::getById(Conference::activeConference()).title());
111         selectConference->setCurrentIndex(idx);
112         connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
113         conferenceChanged(idx);
114     }
115     else
116     {
117         conferenceHeader->hide();
118         selectConferenceWidget->hide();
119         // go to the 'conferenceTab', so the user can import the schedule
120         tabWidget->setCurrentIndex(6); // 6 - conference tab
121     }
122
123     // open dialog for given Event ID
124     // this is used in case Alarm Dialog request application to start
125     if(aEventId)
126     {
127         try
128         {
129             EventDialog dialog(aEventId,this);
130             dialog.exec();
131         }
132         catch(OrmNoObjectException&) {} // just start application
133         catch(...) {} // just start application
134     }
135 }
136
137 void MainWindow::scheduleImported(int aConfId)
138 {
139     Q_UNUSED(aConfId);
140
141     Conference conf = Conference::getById(aConfId);
142     if( selectConference->findText(conf.title()) < 0 ) // item doesn't exist
143     {
144         disconnect(selectConference, SIGNAL(currentIndexChanged(int)), this, SLOT(conferenceChanged(int)));
145         selectConference->addItem(conf.title(),conf.id());
146         connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
147     }
148     int confCount = Conference::getAll().count();
149     if(confCount)
150     {
151         int idx = selectConference->findText(conf.title());
152         selectConference->setCurrentIndex(idx);
153
154         selectConferenceWidget->show();
155
156         conferenceChanged(idx);
157     }
158 }
159
160 void MainWindow::scheduleDeleted(const QString& title)
161 {
162     int idx = selectConference->findText(title);
163
164     if (idx == -1) {
165         // should not happen
166         qWarning() << __PRETTY_FUNCTION__ << "removed non-existent item:" << title;
167         // this happens when you remove the only conference (the list is not ptoperly inited in this case)
168         // now make sure that conferencet
169         if (selectConference->count() > 0) {
170             selectConference->setCurrentIndex(0);
171             conferenceChanged(0);
172         } else {
173             conferenceChanged(-1);
174         }
175     } else {
176         // will it signal "changed"?
177         selectConference->removeItem(idx);
178     }
179 }
180
181 void MainWindow::aboutApp()
182 {
183     QDialog dialog(this);
184     Ui::AboutDialog ui;
185     ui.setupUi(&dialog);
186 #ifdef N810
187     dialog.setFixedWidth(width());
188 #endif
189     dialog.exec();
190 }
191
192 void MainWindow::conferenceMapClicked()
193 {
194     QString mapPath = QString(":/maps/campus.png");
195     if(!QFile::exists(mapPath))
196         mapPath = QString(":/maps/rooms/not-available.png");
197
198     QString roomName;
199
200     QPixmap map(mapPath);
201     MapWindow window(map,roomName,this);
202     window.exec();
203 }
204
205 void MainWindow::eventHasChanged(int aEventId, bool aReloadModel)
206 {
207     dayTabContainer->updateTreeViewModel(aEventId);
208     favsTabContainer->updateTreeViewModel(aEventId,aReloadModel);
209     tracksTabContainer->updateTreeViewModel(aEventId);
210     nowTabContainer->updateTreeViewModel(aEventId);
211     roomsTabContainer->updateTreeViewModel(aEventId);
212     searchTabContainer->updateTreeViewModel(aEventId);
213 }
214
215 void MainWindow::fillAndShowConferenceHeader()
216 {
217     int confId = Conference::activeConference();
218     conferenceTitle->setText(Conference::getById(confId).title());
219     conferenceSubtitle->setText(Conference::getById(confId).subtitle());
220     conferenceWhere->setText(Conference::getById(confId).city() + ", " + Conference::getById(confId).venue());
221     conferenceWhen->setText(
222             Conference::getById(confId).start().toString("dd-MM-yyyy")
223             + ", " +
224             Conference::getById(confId).end().toString("dd-MM-yyyy"));
225     conferenceHeader->show();
226 }
227
228 void MainWindow::initTabs()
229 {
230     int confId = Conference::activeConference();
231     QDate startDate = Conference::getById(confId).start();
232     QDate endDate = Conference::getById(confId).end();
233
234     // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
235     dayTabContainer->setDates(startDate, endDate);
236     tracksTabContainer->setDates(startDate, endDate);
237     roomsTabContainer->setDates(startDate, endDate);
238     favsTabContainer->setDates(startDate, endDate);
239     searchTabContainer->setDates(startDate, endDate);
240     searchTabContainer->searchAgainClicked();
241     nowTabContainer->updateTreeView(QDate::currentDate());
242 }
243
244 void MainWindow::unsetConference()
245 {
246     dayTabContainer->clearModel();
247     tracksTabContainer->clearModel();
248     roomsTabContainer->clearModel();
249     favsTabContainer->clearModel();
250     searchTabContainer->clearModel();
251     searchTabContainer->searchAgainClicked();
252     nowTabContainer->clearModel();
253
254     conferenceHeader->hide();
255     setWindowTitle(saved_title);
256 }
257
258 void MainWindow::conferenceChanged(int aIndex)
259 {
260     if (aIndex < 0) {
261         // no conferences left? reset all views
262         unsetConference();
263         return;
264     }
265
266     try {
267         Conference::getById(Conference::activeConference()).update("active",0);
268         Conference::getById(selectConference->itemData(aIndex).toInt()).update("active",1);
269     } catch (OrmException& e) {
270         // cannon set an active conference
271         unsetConference();
272         return;
273     }
274
275     initTabs();
276     fillAndShowConferenceHeader();
277     setWindowTitle(Conference::getById(Conference::activeConference()).title());
278 }
279
280 void MainWindow::setup()
281 {
282     SettingsDialog dialog;
283     dialog.exec();
284
285     qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
286     QNetworkProxy proxy(
287             AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
288             AppSettings::proxyAddress(),
289             AppSettings::proxyPort(),
290             PROXY_USERNAME,
291             PROXY_PASSWD);
292     QNetworkProxy::setApplicationProxy(proxy);
293 }