import/search schedule dialog implemented
[toast/confclerk.git] / src / gui / mainwindow.cpp
1 #include "mainwindow.h"
2
3 #include <QTreeView>
4 #include <QDirModel>
5
6 #include <sqlengine.h>
7
8 #include <track.h>
9 #include <eventmodel.h>
10 #include <delegate.h>
11
12 #include <conference.h>
13
14 #include <QDialog>
15 #include "ui_about.h"
16 #include "eventdialog.h"
17 #include "daynavigatorwidget.h"
18 #include "importscheduledialog.h"
19 #include "mapwindow.h"
20
21 const int confId = 1;
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     //ACTIVITIES 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     // event clicked
79     connect(dayTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
80     connect(favTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
81     connect(trackTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
82     connect(searchTreeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
83     // request for map to be displayed
84     connect(dayTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
85     connect(favTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
86     connect(trackTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
87     connect(searchTreeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
88     // event search button clicked
89     connect(searchButton, SIGNAL(clicked()), SLOT(searchClicked()));
90
91     // TESTING: load some 'fav' data
92     if(Conference::getAll().count()) // no conference(s) in the DB
93     {
94         static_cast<EventModel*>(favTreeView->model())->loadFavEvents(Conference::getById(confId).start(),confId);
95         favTreeView->reset();
96     }
97
98     if(!Conference::getAll().count()) // no conference(s) in the DB
99     {
100         dayNavigator->hide(); // hide DayNavigatorWidget
101         trackDayNavigator->hide();
102     }
103     else
104     {
105         QDate aStartDate = Conference::getById(confId).start();
106         QDate aEndDate = Conference::getById(confId).end();
107         dayNavigator->setDates(aStartDate, aEndDate);
108         trackDayNavigator->setDates(aStartDate, aEndDate);
109         favouriteDayNavigator->setDates(aStartDate, aEndDate);
110         searchDayNavigator->setDates(aStartDate, aEndDate);
111     }
112
113     connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateTab(int)));
114
115     searchTreeView->hide();
116     searchDayNavigator->hide();
117
118     // open dialog for given Event ID
119     // this is used in case Alarm Dialog request application to start
120     if(aEventId)
121     {
122         try
123         {
124             EventDialog dialog(aEventId,this);
125             dialog.exec();
126         }
127         catch(OrmNoObjectException) {} // just start application
128         catch(...) {} // just start application
129     }
130 }
131
132 MainWindow::~MainWindow()
133 {
134     if(mSqlEngine)
135     {
136         delete mSqlEngine;
137         mSqlEngine = NULL;
138     }
139 }
140
141 void MainWindow::importSchedule()
142 {
143     ImportScheduleDialog dialog(mSqlEngine,this);
144     dialog.exec();
145     
146     if(Conference::getAll().count())
147     {
148         // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
149         QDate aStartDate = Conference::getById(confId).start();
150         QDate aEndDate = Conference::getById(confId).end();
151         dayNavigator->setDates(aStartDate, aEndDate);
152         //update activity map
153         Track::updateTrackMap();
154         trackDayNavigator->setDates(aStartDate, aEndDate);
155     }
156 }
157
158 void MainWindow::aboutApp()
159 {
160     QDialog dialog(this);
161     Ui::AboutDialog ui;
162     ui.setupUi(&dialog);
163     dialog.exec();
164 }
165
166 void MainWindow::updateDayView(const QDate &aDate)
167 {
168     static_cast<EventModel*>(dayTreeView->model())->loadEvents(aDate,confId);
169     dayTreeView->reset();
170     dayNavigator->show();
171 }
172
173 void MainWindow::updateTab(const int aIndex)
174 {
175     switch(aIndex)
176     {
177     case 0://index 0 of tabWidget: dayViewTab
178         {
179             updateDayView(dayNavigator->getCurrentDate());
180         }
181         break;
182     case 1: //index 1 of tabWidget: favouritesTab
183         {
184             updateFavouritesView(favouriteDayNavigator->getCurrentDate());
185         }
186         break;
187     case 2: //index 2 of tabWidget: activitiesTab
188         {
189             updateTracksView(trackDayNavigator->getCurrentDate());
190         }
191         break;
192     case 3: //index 3 of tabWidget: searchTab
193        {
194            updateSearchView( searchDayNavigator->getCurrentDate() );
195        }
196        break;
197     default:
198         {
199
200         }
201     };
202 }
203
204 void MainWindow::updateTracksView(const QDate &aDate)
205 {
206     static_cast<EventModel*>(trackTreeView->model())->loadEventsByTrack(aDate, confId);
207     trackTreeView->reset();
208     trackDayNavigator->show();
209 }
210
211 void MainWindow::updateFavouritesView(const QDate &aDate)
212 {
213     static_cast<EventModel*>(favTreeView->model())->loadFavEvents(aDate,confId);
214     favTreeView->reset();
215     favouriteDayNavigator->show();
216 }
217
218 void MainWindow::updateSearchView(const QDate &aDate)
219 {
220     searchTreeView->reset();
221     int eventsCount = static_cast<EventModel*>(searchTreeView->model())->loadSearchResultEvents(aDate,confId);
222     if( eventsCount ){
223         searchDayNavigator->show();
224         searchTreeView->show();
225     }
226     else{
227         searchTreeView->hide();
228         searchDayNavigator->hide();
229     }
230 }
231
232 void MainWindow::itemClicked(const QModelIndex &aIndex)
233 {
234     // have to handle only events, not time-groups
235     if(!aIndex.parent().isValid()) // time-group
236         return;
237
238     EventDialog dialog(static_cast<Event*>(aIndex.internalPointer())->id(),this);
239     dialog.exec();
240 }
241
242 void MainWindow::displayMap(const QModelIndex &aIndex)
243 {
244     Event *event = static_cast<Event*>(aIndex.internalPointer());
245
246     // room names are stored in lower-case format
247     // room names are stored without dots in the name, eg. "aw.1124.png" -> "aw1124.png"
248     QString mapPath = QString(":/maps/rooms/%1.png").arg(event->room().toLower().remove("."));
249     if(!QFile::exists(mapPath))
250         mapPath = QString(":/maps/rooms/not-available.png");
251
252     QString roomName;
253     if(mapPath.contains("not-available", Qt::CaseInsensitive))
254         roomName = QString("Map is not available: %1").arg(event->room());
255     else
256         roomName = event->room();
257
258     QPixmap map(mapPath);
259     MapWindow window(map,roomName,this);
260     window.exec();
261 }
262
263 void MainWindow::searchClicked()
264 {
265     QList<QString> columns;
266
267     if( searchTitle->isChecked() )
268         columns.append( "title" );
269     if( searchAbstract->isChecked() )
270         columns.append( "abstract" );
271
272     mSqlEngine->searchEvent( confId, columns, searchEdit->text() );
273     updateSearchView( Conference::getById(confId).start() );
274 }
275