c57702afd79e881bdd92a5b3e8cb16a57e221645
[toast/confclerk.git] / src / mvc / eventmodel.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 "eventmodel.h"
20 #include <conference.h>
21 #include <track.h>
22 #include <room.h>
23
24 const QString EventModel::COMMA_SEPARATOR = ", ";
25
26 EventModel::EventModel()
27 { }
28
29 void EventModel::createTimeGroups()
30 {
31     mGroups.clear();
32     mParents.clear();
33
34     if (mEvents.empty())
35     {
36         return;
37     }
38
39     const int timeSpan = 5400;
40
41     QTime startTime = mEvents.first().start().time();
42     mGroups << EventModel::Group(QString("%1 - %2").arg(startTime.toString("HH:mm"),
43         startTime.addSecs(timeSpan).toString("HH:mm")), 0);
44     QTime nextGroupTime = mEvents.first().start().time().addSecs(timeSpan);
45
46     for (int i=0; i<mEvents.count(); i++)
47     {
48         QTime eventTime = mEvents.at(i).start().time();
49
50         if (nextGroupTime <= eventTime)
51         {
52             mGroups.last().mChildCount = i - mGroups.last().mFirstEventIndex;
53             mGroups << EventModel::Group(QString("%1 - %2").arg(nextGroupTime.toString("HH:mm"),
54                 nextGroupTime.addSecs(timeSpan).toString("HH:mm")), i);
55             nextGroupTime = nextGroupTime.addSecs(timeSpan);
56         }
57
58         // add parent-child relation
59         mParents[mEvents.at(i).id()] = mGroups.count() - 1;
60     }
61
62     mGroups.last().mChildCount = mEvents.count() - mGroups.last().mFirstEventIndex;
63
64     reset();
65 }
66
67 void EventModel::createTrackGroups() {
68     mGroups.clear();
69     mParents.clear();
70     if (mEvents.empty())
71     {
72         return;
73     }
74     int trackId = mEvents.first().trackId();
75
76     mGroups << EventModel::Group(Track::retrieveTrackName(trackId), 0);
77     int nextTrackId = trackId;
78
79     for (int i=0; i<mEvents.count(); i++)
80     {
81         trackId = mEvents.at(i).trackId();
82         if (nextTrackId != trackId)
83         {
84             mGroups.last().mChildCount = i - mGroups.last().mFirstEventIndex;
85             mGroups << EventModel::Group(Track::retrieveTrackName(trackId), i);
86             nextTrackId = trackId;
87         }
88         // add parent-child relation
89         mParents[mEvents.at(i).id()] = mGroups.count() - 1;
90     }
91     mGroups.last().mChildCount = mEvents.count() - mGroups.last().mFirstEventIndex;
92 }
93
94 void EventModel::createRoomGroups()
95 {
96     mGroups.clear();
97     mParents.clear();
98     if (mEvents.empty())
99     {
100         return;
101     }
102     int roomId = mEvents.first().roomId();
103
104     mGroups << EventModel::Group(Room::retrieveRoomName(roomId), 0);
105     int nextRoomId = roomId;
106
107     QList<Event>::iterator event = mEvents.begin();
108     int i = 0;
109     while (event != mEvents.end())
110     {
111         roomId = event->roomId();
112         if (nextRoomId != roomId)
113         {
114             mGroups.last().mChildCount = i - mGroups.last().mFirstEventIndex;
115             mGroups << EventModel::Group(Room::retrieveRoomName(roomId), i);
116             nextRoomId = roomId;
117         }
118         mParents[event->id()] = mGroups.count() - 1;
119         event++;
120         i++;
121     }
122     mGroups.last().mChildCount = mEvents.count() - mGroups.last().mFirstEventIndex;
123 }
124
125 QVariant EventModel::data(const QModelIndex& index, int role) const
126 {
127     if (index.isValid() && role == Qt::DisplayRole)
128     {
129         if (index.internalId() == 0)
130         {
131             return mGroups.at(index.row()).mTitle;
132         }
133         else //event data
134         {
135             return static_cast<Event*>(index.internalPointer())->id();
136         }
137     }
138
139     return QVariant();
140 }
141
142 QModelIndex EventModel::index(int row, int column, const QModelIndex& parent) const
143 {
144     // TODO: add checks for out of range rows
145
146     if (!parent.isValid())
147     {
148         return createIndex(row, column, 0);
149     }
150     else if (parent.internalId() == 0)
151     {
152         const Group& group = mGroups.at(parent.row());
153         Event* event = const_cast<Event*>(&mEvents.at(row + group.mFirstEventIndex));
154         return createIndex(row, column, reinterpret_cast<void*>(event));
155     }
156     else
157     {
158         return QModelIndex();
159     }
160 }
161
162 QModelIndex EventModel::parent(const QModelIndex & index) const
163 {
164     if (index.isValid())
165     {
166         if (index.internalId() == 0)
167         {
168             return QModelIndex();
169         }
170
171         Event * event = static_cast<Event*>(index.internalPointer());
172
173         return createIndex(mParents[event->id()], 0, 0);
174     }
175
176     return QModelIndex();
177 }
178
179 int EventModel::columnCount(const QModelIndex & parent) const
180 {
181     Q_UNUSED(parent);
182     return 1;
183 }
184
185 int EventModel::rowCount (const QModelIndex & parent) const
186 {
187     if (!parent.isValid())
188     {
189         return mGroups.count();
190     }
191
192     if (parent.internalId() == 0)
193     {
194         return mGroups.at(parent.row()).mChildCount;
195     }
196
197     return 0;
198 }
199
200 void EventModel::clearModel()
201 {
202     qDebug() << __PRETTY_FUNCTION__ << this << mEvents.count();
203     mGroups.clear();
204     mEvents.clear();
205     mParents.clear();
206
207     reset();
208 }
209
210 void EventModel::loadEvents(const QDate &aDate, int aConferenceId)
211 {
212     clearModel();
213     // check for existence of the conference in the DB
214     if(Conference::getAll().count())
215     {
216         qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
217         mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start");
218     }
219     createTimeGroups();
220 }
221
222 void EventModel::loadFavEvents(const QDate &aDate, int aConferenceId)
223 {
224     clearModel();
225     // check for existence of the conference in the DB
226     if(Conference::getAll().count())
227     {
228         qDebug() << "Loading FAV Conference Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
229         mEvents = Event::getFavByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
230     }
231     createTimeGroups();
232 }
233
234 int EventModel::loadSearchResultEvents(const QDate &aDate, int aConferenceId)
235 {
236     clearModel();
237     // check for existence of the conference in the DB
238     if(Conference::getAll().count())
239     {
240         qDebug() << "Loading search result Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
241         try{
242             mEvents = Event::getSearchResultByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start");
243         }
244         catch( OrmException &e  ){
245             qDebug() << "Event::getSearchResultByDate failed: " << e.text();
246         }
247         catch(...){
248             qDebug() << "Event::getSearchResultByDate failed";
249         }
250
251     }
252
253     createTimeGroups();
254
255     return mEvents.count();
256 }
257
258 void EventModel::loadEventsByTrack(const QDate &aDate, int aConferenceId)
259 {
260     clearModel();
261     if (Conference::getAll().count())
262     {
263         qDebug() << "Loading Conference Data (by Track): [" << Conference::getById(aConferenceId).title() << "] " << aDate;
264         mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "xid_track, start");
265     }
266     createTrackGroups();
267 }
268
269 void EventModel::loadEventsByRoom(const QDate &aDate, int aConferenceId)
270 {
271     clearModel();
272     if (Conference::getAll().count())
273     {
274         qDebug() << "Loading Conference Data (by Room): [" << Conference::getById(aConferenceId).title() << "] " << aDate;
275         mEvents = Event::getByDateAndRoom(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
276     }
277     createRoomGroups();
278 }
279
280 void EventModel::loadNowEvents(int aConferenceId)
281 {
282     clearModel();
283     // check for existence of the conference in the DB
284     if(Conference::getAll().count())
285     {
286         qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] scheduled NOW";
287         mEvents = Event::nowEvents(aConferenceId, "start");
288     }
289     createTimeGroups();
290 }
291
292 void EventModel::loadConflictEvents(int aEventId, int aConferenceId)
293 {
294     clearModel();
295     // check for existence of the conference in the DB
296     if(Conference::getAll().count())
297     {
298         qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] in conflict with " << aEventId;
299         mEvents = Event::conflictEvents(aEventId, aConferenceId);
300     }
301     createTimeGroups();
302 }
303
304 void EventModel::updateModel(int aEventId)
305 {
306     for(int i=0; i<mEvents.count(); i++)
307     {
308         if(mEvents[i].id() == aEventId)
309             mEvents[i] = Event::getById(aEventId,Conference::activeConference());
310     }
311
312     // find the ModelIndex for given aEventId
313     for(int i=0; i<mGroups.count(); i++)
314     {
315         QModelIndex groupIndex = index(i,0,QModelIndex());
316         for(int j=0; j<mGroups[i].mChildCount; j++)
317         {
318             QModelIndex eventIndex = index(j,0,groupIndex);
319             if(static_cast<Event*>(eventIndex.internalPointer())->id() == aEventId)
320             {
321                 emit(dataChanged(groupIndex,groupIndex));
322                 emit(dataChanged(eventIndex,eventIndex));
323             }
324         }
325     }
326 }
327