implemented NOW tab
[toast/confclerk.git] / src / gui / mainwindow.cpp
1 #include "mainwindow.h"
2 #include <appsettings.h>
3
4 #include <QTreeView>
5 #include <QDirModel>
6
7 #include <sqlengine.h>
8
9 #include <track.h>
10 #include <eventmodel.h>
11 #include <delegate.h>
12
13 #include <conference.h>
14
15 #include <QDialog>
16 #include <QMessageBox>
17 #include "ui_about.h"
18 #include "eventdialog.h"
19 #include "daynavigatorwidget.h"
20 #include "importscheduledialog.h"
21 #include "mapwindow.h"
22
23 MainWindow::MainWindow(int aEventId, QWidget *aParent)
24     : QMainWindow(aParent)
25 {
26     setupUi(this);
27
28     // connect Menu actions
29     connect(actionImportSchedule, SIGNAL(triggered()), SLOT(importSchedule()));
30     connect(actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
31     connect(actionAboutApplication, SIGNAL(triggered()), SLOT(aboutApp()));
32
33     // create "SQLITE" DB instance/connection
34     // opens DB connection (needed for EventModel)
35     mSqlEngine = new SqlEngine(this);
36     mSqlEngine->initialize();
37
38     //update track map
39     Track::updateTrackMap();
40
41     connect(dayNavigator, SIGNAL(dateChanged(const QDate &)), SLOT(updateDayView(const QDate &)));
42     connect(trackDayNavigator, SIGNAL(dateChanged(const QDate &)), SLOT(updateTracksView(const QDate &)));
43     connect(favouriteDayNavigator, SIGNAL(dateChanged(const QDate &)), SLOT(updateFavouritesView(const QDate &)));
44     connect(searchDayNavigator, SIGNAL(dateChanged(const QDate &)), SLOT(updateSearchView(const QDate &)));
45
46     // DAY EVENTS View
47     dayTreeView->setHeaderHidden(true);
48     dayTreeView->setRootIsDecorated(false);
49     dayTreeView->setIndentation(0);
50     dayTreeView->setAnimated(true);
51     dayTreeView->setModel(new EventModel());
52     dayTreeView->setItemDelegate(new Delegate(dayTreeView));
53
54     // FAVOURITIES View
55     favTreeView->setHeaderHidden(true);
56     favTreeView->setRootIsDecorated(false);
57     favTreeView->setIndentation(0);
58     favTreeView->setAnimated(true);
59     favTreeView->setModel(new EventModel());
60     favTreeView->setItemDelegate(new Delegate(favTreeView));
61
62     // TRACKS View
63     trackTreeView->setHeaderHidden(true);
64     trackTreeView->setRootIsDecorated(false);
65     trackTreeView->setIndentation(0);
66     trackTreeView->setAnimated(true);
67     trackTreeView->setModel(new EventModel());
68     trackTreeView->setItemDelegate(new Delegate(trackTreeView));
69
70     // SEARCH EVENTS View
71         searchTreeView->setHeaderHidden(true);
72         searchTreeView->setRootIsDecorated(false);
73         searchTreeView->setIndentation(0);
74         searchTreeView->setAnimated(true);
75         searchTreeView->setModel(new EventModel());
76         searchTreeView->setItemDelegate(new Delegate(searchTreeView));
77
78     // NOW View
79         nowTreeView->setHeaderHidden(true);
80         nowTreeView->setRootIsDecorated(false);
81         nowTreeView->setIndentation(0);
82         nowTreeView->setAnimated(true);
83         nowTreeView->setModel(new EventModel());
84         nowTreeView->setItemDelegate(new Delegate(nowTreeView));
85
86     // event details have changed
87     connect(dayTreeView, SIGNAL(eventHasChanged(int)), SLOT(eventHasChanged(int)));
88     connect(favTreeView, SIGNAL(eventHasChanged(int)), SLOT(eventHasChanged(int)));
89     connect(trackTreeView, SIGNAL(eventHasChanged(int)), SLOT(eventHasChanged(int)));
90     connect(searchTreeView, SIGNAL(eventHasChanged(int)), SLOT(eventHasChanged(int)));
91     connect(nowTreeView, SIGNAL(eventHasChanged(int)), SLOT(eventHasChanged(int)));
92
93     // event clicked
94     connect(dayTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
95     connect(favTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
96     connect(trackTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
97     connect(searchTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
98     connect(nowTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
99     // request for map to be displayed
100     connect(dayTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
101     connect(favTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
102     connect(trackTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
103     connect(searchTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
104     connect(nowTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
105     // request for warning to be displayed
106     connect(dayTreeView, SIGNAL(requestForWarning(const QModelIndex &)), SLOT(displayWarning(const QModelIndex &)));
107     connect(favTreeView, SIGNAL(requestForWarning(const QModelIndex &)), SLOT(displayWarning(const QModelIndex &)));
108     connect(trackTreeView, SIGNAL(requestForWarning(const QModelIndex &)), SLOT(displayWarning(const QModelIndex &)));
109     connect(searchTreeView, SIGNAL(requestForWarning(const QModelIndex &)), SLOT(displayWarning(const QModelIndex &)));
110     connect(nowTreeView, SIGNAL(requestForWarning(const QModelIndex &)), SLOT(displayWarning(const QModelIndex &)));
111     // event search button clicked
112     connect(searchButton, SIGNAL(clicked()), SLOT(searchClicked()));
113     //
114     connect(tabWidget, SIGNAL(currentChanged(int)), SLOT(tabHasChanged(int)));
115
116     if(!Conference::getAll().count()) // no conference(s) in the DB
117     {
118         dayNavigator->hide(); // hide DayNavigatorWidget
119         trackDayNavigator->hide();
120     }
121     else
122     {
123         QDate aStartDate = Conference::getById(AppSettings::confId()).start();
124         QDate aEndDate = Conference::getById(AppSettings::confId()).end();
125         dayNavigator->setDates(aStartDate, aEndDate);
126         trackDayNavigator->setDates(aStartDate, aEndDate);
127         favouriteDayNavigator->setDates(aStartDate, aEndDate);
128         searchDayNavigator->setDates(aStartDate, aEndDate);
129         //
130         conferenceTitle->setText(Conference::getById(AppSettings::confId()).title());
131         conferenceSubtitle->setText(Conference::getById(AppSettings::confId()).subtitle());
132         conferenceWhere->setText(Conference::getById(AppSettings::confId()).city() + ", " + Conference::getById(AppSettings::confId()).venue());
133         conferenceWhen->setText(
134                 Conference::getById(AppSettings::confId()).start().toString("dd-MM-yyyy")
135                 + ", " +
136                 Conference::getById(AppSettings::confId()).end().toString("dd-MM-yyyy"));
137     }
138
139     searchTreeView->hide();
140     searchDayNavigator->hide();
141
142     // open dialog for given Event ID
143     // this is used in case Alarm Dialog request application to start
144     if(aEventId)
145     {
146         try
147         {
148             EventDialog dialog(aEventId,this);
149             dialog.exec();
150         }
151         catch(OrmNoObjectException) {} // just start application
152         catch(...) {} // just start application
153     }
154 }
155
156 MainWindow::~MainWindow()
157 {
158     if(mSqlEngine)
159     {
160         delete mSqlEngine;
161         mSqlEngine = NULL;
162     }
163 }
164
165 void MainWindow::importSchedule()
166 {
167     ImportScheduleDialog dialog(mSqlEngine,this);
168     dialog.exec();
169     
170     if(Conference::getAll().count())
171     {
172         // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
173         QDate aStartDate = Conference::getById(AppSettings::confId()).start();
174         QDate aEndDate = Conference::getById(AppSettings::confId()).end();
175         dayNavigator->setDates(aStartDate, aEndDate);
176         //update activity map
177         Track::updateTrackMap();
178         trackDayNavigator->setDates(aStartDate, aEndDate);
179     }
180 }
181
182 void MainWindow::aboutApp()
183 {
184     QDialog dialog(this);
185     Ui::AboutDialog ui;
186     ui.setupUi(&dialog);
187     dialog.exec();
188 }
189
190 void MainWindow::updateDayView(const QDate &aDate)
191 {
192     static_cast<EventModel*>(dayTreeView->model())->loadEvents(aDate,AppSettings::confId());
193     dayTreeView->reset();
194     dayNavigator->show();
195 }
196
197 void MainWindow::updateTracksView(const QDate &aDate)
198 {
199     static_cast<EventModel*>(trackTreeView->model())->loadEventsByTrack(aDate, AppSettings::confId());
200     trackTreeView->reset();
201     trackDayNavigator->show();
202 }
203
204 void MainWindow::updateFavouritesView(const QDate &aDate)
205 {
206     static_cast<EventModel*>(favTreeView->model())->loadFavEvents(aDate,AppSettings::confId());
207     favTreeView->reset();
208     favouriteDayNavigator->show();
209 }
210
211 void MainWindow::updateSearchView(const QDate &aDate)
212 {
213     searchTreeView->reset();
214     int eventsCount = static_cast<EventModel*>(searchTreeView->model())->loadSearchResultEvents(aDate,AppSettings::confId());
215     if( eventsCount ){
216         searchDayNavigator->show();
217         searchTreeView->show();
218     }
219     else{
220         searchTreeView->hide();
221         searchDayNavigator->hide();
222     }
223 }
224
225 void MainWindow::updateNowView()
226 {
227     EventModel *model = static_cast<EventModel*>(nowTreeView->model());
228     model->loadNowEvents(AppSettings::confId());
229     nowTreeView->reset();
230     nowTreeView->setAllExpanded(true);
231 }
232
233 void MainWindow::itemClicked(const QModelIndex &aIndex)
234 {
235     // have to handle only events, not time-groups
236     if(!aIndex.parent().isValid()) // time-group
237         return;
238
239     EventDialog dialog(static_cast<Event*>(aIndex.internalPointer())->id(),this);
240     dialog.exec();
241 }
242
243 void MainWindow::displayMap(const QModelIndex &aIndex)
244 {
245     Event *event = static_cast<Event*>(aIndex.internalPointer());
246
247     // room names are stored in lower-case format
248     // room names are stored without dots in the name, eg. "aw.1124.png" -> "aw1124.png"
249     QString mapPath = QString(":/maps/rooms/%1.png").arg(event->room().toLower().remove("."));
250     if(!QFile::exists(mapPath))
251         mapPath = QString(":/maps/rooms/not-available.png");
252
253     QString roomName;
254     if(mapPath.contains("not-available", Qt::CaseInsensitive))
255         roomName = QString("Map is not available: %1").arg(event->room());
256     else
257         roomName = event->room();
258
259     QPixmap map(mapPath);
260     MapWindow window(map,roomName,this);
261     window.exec();
262 }
263
264 void MainWindow::searchClicked()
265 {
266     QList<QString> columns;
267
268     if( searchTitle->isChecked() )
269         columns.append( "title" );
270     if( searchAbstract->isChecked() )
271         columns.append( "abstract" );
272
273     mSqlEngine->searchEvent( AppSettings::confId(), columns, searchEdit->text() );
274     updateSearchView( Conference::getById(AppSettings::confId()).start() );
275 }
276
277 void MainWindow::displayWarning(const QModelIndex &aIndex)
278 {
279     Q_UNUSED(aIndex);
280
281     QMessageBox::warning(
282     this,
283     tr("Time Conflict Warning"),
284     tr("This event happens at the same time than another one of your favourites.") );
285 }
286
287 void MainWindow::eventHasChanged(int aEventId)
288 {
289     static_cast<EventModel*>(dayTreeView->model())->updateModel(aEventId);
290     static_cast<EventModel*>(favTreeView->model())->updateModel(aEventId);
291     static_cast<EventModel*>(trackTreeView->model())->updateModel(aEventId);
292     static_cast<EventModel*>(searchTreeView->model())->updateModel(aEventId);
293     static_cast<EventModel*>(nowTreeView->model())->updateModel(aEventId);
294 }
295
296 void MainWindow::tabHasChanged(int aIndex)
297 {
298     Q_UNUSED(aIndex);
299
300     // TODO: only if it changed to favourities tab
301     updateFavouritesView(favouriteDayNavigator->getCurrentDate());
302     // TODO: only if it changed to now tab
303     updateNowView();
304 }
305