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