1 /* |
1 /* |
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
3 * All rights reserved. |
3 * All rights reserved. |
4 * This component and the accompanying materials are made available |
4 * This component and the accompanying materials are made available |
5 * under the terms of "Eclipse Public License v1.0" |
5 * under the terms of "Eclipse Public License v1.0" |
6 * which accompanies this distribution, and is available |
6 * which accompanies this distribution, and is available |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
8 * |
8 * |
9 * Initial Contributors: |
9 * Initial Contributors: |
10 * Nokia Corporation - initial contribution. |
10 * Nokia Corporation - initial contribution. |
11 * |
11 * |
12 * Contributors: |
12 * Contributors: |
13 * |
13 * |
14 * Description: Day view control of calendar |
14 * Description: Day view container - parent widget for events (CalenDayItem) |
15 * |
15 * and hours area widgets (CalenDayEventsPane) |
16 */ |
16 * Responsible for positioning and resizing events widgets. |
|
17 */ |
17 |
18 |
18 //System includes |
19 //System includes |
19 #include <QTime> |
20 #include <QTime> |
20 #include <QGraphicsLinearLayout> |
21 #include <QGraphicsLinearLayout> |
21 #include <QGesture> |
22 #include <QGesture> |
22 |
23 |
23 #ifdef _DEBUG |
24 #ifdef _DEBUG |
24 #include <QPainter> |
25 #include <QPainter> |
25 #endif |
26 #endif |
26 |
27 |
27 #include <hbabstractitemview.h> |
28 #include <HbAbstractItemView> |
28 #include <hbtextitem.h> |
29 #include <HbTextItem> |
29 #include <hbmodeliterator.h> |
30 #include <HbModelIterator> |
30 #include <hbinstance.h> |
31 #include <HbInstance> |
31 |
32 |
32 //User includes |
33 //User includes |
33 #include "calendaycontainer.h" |
34 #include "calendaycontainer.h" |
34 #include "calendayutils.h" |
35 #include "calendayutils.h" |
35 #include "calendayeventspane.h" |
36 #include "calendayeventspane.h" |
36 #include "calendayitem.h" |
37 #include "calendayitem.h" |
37 #include "calendaymodel.h" |
38 #include "calendaymodel.h" |
38 #include "calendayinfo.h" |
39 #include "calendayinfo.h" |
39 #include "calendayview.h" |
40 #include "calendayview.h" |
40 |
41 #include "calenagendautils.h" |
41 // ----------------------------------------------------------------------------- |
42 #include "calendaycommonheaders.h" |
42 // CalenDayContainer() |
43 |
43 // Constructor |
44 /*! |
44 // ----------------------------------------------------------------------------- |
45 \class CalenDayContainer |
45 // |
46 |
|
47 \brief CalenDayContainer Item container class associated with model. |
|
48 */ |
|
49 |
|
50 /*! |
|
51 \brief Constructor |
|
52 |
|
53 Sets container initial geometry, creates hours area widgets. |
|
54 \param parent Parent object |
|
55 */ |
46 CalenDayContainer::CalenDayContainer(QGraphicsItem *parent) : |
56 CalenDayContainer::CalenDayContainer(QGraphicsItem *parent) : |
47 HbAbstractItemContainer(parent), mGeometryUpdated(false), mInfo(0) |
57 HbAbstractItemContainer(parent), mGeometryUpdated(false), mInfo(0) |
48 { |
58 { |
49 getTimedEventLayoutValues(mLayoutValues); |
59 getTimedEventLayoutValues(mLayoutValues); |
50 |
60 |
51 // Get the height of element |
|
52 qreal paneHeight = CalenDayUtils::instance()->hourElementHeight(); |
|
53 |
|
54 QGraphicsLinearLayout* timeLinesLayout = new QGraphicsLinearLayout( |
61 QGraphicsLinearLayout* timeLinesLayout = new QGraphicsLinearLayout( |
55 Qt::Vertical, this); |
62 Qt::Vertical, this); |
56 for (int i = 0; i < 24; i++) { |
63 for (int i = 0; i < KCalenHoursInDay; i++) { |
57 CalenDayEventsPane* element = new CalenDayEventsPane(this); |
64 CalenDayEventsPane* element = new CalenDayEventsPane(this); |
58 element->setPreferredHeight(paneHeight); |
65 // Draw top line at midnight |
59 element->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); |
|
60 // Draw top line at midnight |
|
61 if (i == 0) { |
66 if (i == 0) { |
62 element->drawTopLine(true); |
67 element->setDrawTopLine(true); |
63 } |
68 } |
64 timeLinesLayout->addItem(element); |
69 timeLinesLayout->addItem(element); |
65 } |
70 } |
66 timeLinesLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0); |
71 timeLinesLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0); |
67 timeLinesLayout->setSpacing(0.0); |
72 timeLinesLayout->setSpacing(0.0); |
68 |
73 |
69 setLayout(timeLinesLayout); |
74 setLayout(timeLinesLayout); |
70 } |
75 } |
71 |
76 |
72 // ----------------------------------------------------------------------------- |
77 /*! |
73 // ~CalenDayContainer() |
78 \brief Destructor |
74 // Destructor |
79 */ |
75 // ----------------------------------------------------------------------------- |
|
76 // |
|
77 CalenDayContainer::~CalenDayContainer() |
80 CalenDayContainer::~CalenDayContainer() |
78 { |
81 { |
79 } |
82 // Remove absorbers if exist |
80 |
83 if (mAbsorbers.count()) { |
81 // ----------------------------------------------------------------------------- |
84 qDeleteAll(mAbsorbers); |
82 // itemAdded() |
85 mAbsorbers.clear(); |
83 // |
86 } |
84 // ----------------------------------------------------------------------------- |
87 } |
85 // |
88 |
86 void CalenDayContainer::itemAdded( int index, HbAbstractViewItem *item, |
89 /* |
87 bool animate ) |
90 \reimp |
|
91 */ |
|
92 void CalenDayContainer::itemAdded( |
|
93 int index, |
|
94 HbAbstractViewItem *item, |
|
95 bool animate) |
88 { |
96 { |
89 Q_UNUSED( index ) |
97 Q_UNUSED( index ) |
90 Q_UNUSED( item ) |
98 Q_UNUSED( item ) |
91 Q_UNUSED( animate ) |
99 Q_UNUSED( animate ) |
92 } |
100 } |
93 |
101 |
94 // ----------------------------------------------------------------------------- |
102 |
95 // reset() |
103 /* |
96 // |
104 \brief Resets the state of container. |
97 // ----------------------------------------------------------------------------- |
105 |
98 // |
106 Removes absorbers, gets layout values and maintains current position. |
|
107 */ |
99 void CalenDayContainer::reset() |
108 void CalenDayContainer::reset() |
100 { |
109 { |
101 // remove absorbers if exist |
110 // Remove absorbers if exist |
102 if (mAbsorbers.count()) |
111 if (mAbsorbers.count()) { |
103 { |
112 qDeleteAll(mAbsorbers); |
104 qDeleteAll(mAbsorbers); |
113 mAbsorbers.clear(); |
105 mAbsorbers.clear(); |
114 } |
106 } |
115 |
107 |
116 // Shrink event area when all-day events available after reset |
108 // shrink event area when all-day events available after reset |
117 getTimedEventLayoutValues(mLayoutValues); |
109 getTimedEventLayoutValues(mLayoutValues); |
118 |
110 |
119 // Position need to be maintained while changing model |
111 // position need to be maintained while changing model |
|
112 QPointF position(pos()); |
120 QPointF position(pos()); |
113 HbAbstractItemContainer::reset(); |
121 HbAbstractItemContainer::reset(); |
114 setPos( position ); |
122 setPos(position); |
115 } |
123 } |
116 |
124 |
117 // ----------------------------------------------------------------------------- |
125 /* |
118 // itemRemoved() |
126 \reimp |
119 // |
127 */ |
120 // ----------------------------------------------------------------------------- |
128 void CalenDayContainer::itemRemoved(HbAbstractViewItem *item, bool animate) |
121 // |
|
122 void CalenDayContainer::itemRemoved( HbAbstractViewItem *item, bool animate ) |
|
123 { |
129 { |
124 Q_UNUSED( item ) |
130 Q_UNUSED( item ) |
125 Q_UNUSED( animate ) |
131 Q_UNUSED( animate ) |
126 } |
132 } |
127 |
133 |
128 // ----------------------------------------------------------------------------- |
134 /* |
129 // viewResized() |
135 \reimp |
130 // |
136 */ |
131 // ----------------------------------------------------------------------------- |
137 void CalenDayContainer::viewResized(const QSizeF &size) |
132 // |
|
133 void CalenDayContainer::viewResized (const QSizeF &size) |
|
134 { |
138 { |
135 resize(size); |
139 resize(size); |
136 if (!mGeometryUpdated) { |
140 if (!mGeometryUpdated) { |
137 mGeometryUpdated = true; |
141 mGeometryUpdated = true; |
138 updateGeometry(); |
142 updateGeometry(); |
139 } |
143 } |
140 } |
144 } |
141 |
145 |
142 // ----------------------------------------------------------------------------- |
146 /* |
143 // createDefaultPrototype() |
147 \reimp |
144 // |
148 */ |
145 // ----------------------------------------------------------------------------- |
|
146 // |
|
147 HbAbstractViewItem * CalenDayContainer::createDefaultPrototype() const |
149 HbAbstractViewItem * CalenDayContainer::createDefaultPrototype() const |
148 { |
150 { |
149 CalenDayItem *calendarViewItem = new CalenDayItem; |
151 CalenDayItem *calendarViewItem = new CalenDayItem(this); |
150 return calendarViewItem; |
152 return calendarViewItem; |
151 } |
153 } |
152 |
154 |
153 // ----------------------------------------------------------------------------- |
155 /* |
154 // setItemModelIndex() |
156 \reimp |
155 // |
157 */ |
156 // ----------------------------------------------------------------------------- |
158 void CalenDayContainer::setItemModelIndex( |
157 // |
159 HbAbstractViewItem *item, |
158 void CalenDayContainer::setItemModelIndex(HbAbstractViewItem *item, |
160 const QModelIndex &index) |
159 const QModelIndex &index) |
161 { |
160 { |
162 QVariant variant = index.data(CalenDayEntry); |
161 QVariant variant = index.data( CalenDayEntry ); |
163 AgendaEntry entry = variant.value<AgendaEntry> (); |
162 AgendaEntry entry = variant.value<AgendaEntry>(); |
164 |
163 |
165 // Check for All Day Events and Timed entries |
164 if (entry.isTimedEntry()) { |
166 if (CalenAgendaUtils::isAlldayEvent(entry)) { |
165 updateTimedEventGeometry( item, index ); |
167 updateAllDayEventGeometry(item, index); |
166 item->setParentItem(this); |
168 item->setParentItem(this); |
167 } |
169 } |
168 else if( entry.type() == AgendaEntry::TypeEvent ){ |
170 else |
169 updateAllDayEventGeometry( item, index ); |
171 if (entry.isTimedEntry()) { |
170 item->setParentItem(this); |
172 updateTimedEventGeometry(item, index); |
171 } |
173 item->setParentItem(this); |
172 else { |
174 } |
173 item->setVisible(false); |
175 else { |
174 } |
176 item->setVisible(false); |
175 |
177 } |
176 // last item |
178 |
|
179 // Create touch event absorbers after last item |
177 if (index.row() == index.model()->rowCount() - 1) { |
180 if (index.row() == index.model()->rowCount() - 1) { |
178 createTouchEventAbsorbers(); |
181 createTouchEventAbsorbers(); |
179 } |
182 } |
180 |
183 |
181 HbAbstractItemContainer::setItemModelIndex(item, index); |
184 HbAbstractItemContainer::setItemModelIndex(item, index); |
182 } |
185 } |
183 |
186 |
184 // ----------------------------------------------------------------------------- |
187 |
185 // updateTimedEventGeometry() |
188 /*! |
186 // Updates geometry of a timed event. |
189 \brief Set size and position of singe timed event widget (bubble) |
187 // ----------------------------------------------------------------------------- |
190 \a item bubble widget |
188 // |
191 \a index pointing item data in model |
189 void CalenDayContainer::updateTimedEventGeometry(HbAbstractViewItem *item, |
192 */ |
190 const QModelIndex &index) |
193 void CalenDayContainer::updateTimedEventGeometry( |
191 { |
194 HbAbstractViewItem *item, |
192 //safety check |
195 const QModelIndex &index) |
193 if ( !mInfo ) { |
196 { |
|
197 // Safety check |
|
198 if (!mInfo) { |
194 return; |
199 return; |
195 } |
200 } |
196 |
201 |
197 QVariant variant = index.data( CalenDayEntry ); |
202 QVariant variant = index.data(CalenDayEntry); |
198 AgendaEntry entry = variant.value<AgendaEntry>(); |
203 AgendaEntry entry = variant.value<AgendaEntry> (); |
199 |
204 |
200 //1. get 'virtual' event position from DayInfo |
205 // 1. Get 'virtual' event position from DayInfo |
201 //TODO: k.g.: Day Info should store model index instead of keeping redundant data |
|
202 SCalenApptInfo apptInfo; |
206 SCalenApptInfo apptInfo; |
203 apptInfo.iIndex = index; |
207 apptInfo.iIndex = index; |
204 |
208 |
205 QDateTime start; |
209 QDateTime start; |
206 QDateTime end; |
210 QDateTime end; |
207 QDateTime currentDate; |
211 QDateTime currentDate; |
208 currentDate = static_cast<const CalenDayModel*>(index.model())->modelDate(); |
212 currentDate |
209 CalenDayUtils::instance()->getEventValidStartEndTime( start, end, entry, |
213 = static_cast<const CalenDayModel*> (index.model())->modelDate(); |
210 currentDate ); |
214 CalenDayUtils::instance()->getEventValidStartEndTime(start, end, entry, |
|
215 currentDate); |
211 apptInfo.iStartTime = start; |
216 apptInfo.iStartTime = start; |
212 apptInfo.iEndTime = end; |
217 apptInfo.iEndTime = end; |
213 |
218 |
214 TCalenInstanceId id = TCalenInstanceId::nullInstanceId(); |
219 TCalenInstanceId id = TCalenInstanceId::nullInstanceId(); |
215 id.mEntryLocalUid = index.row(); //index.row() - temporary ID |
220 id.mEntryLocalUid = index.row(); //index.row() - temporary ID |
216 id.mInstanceTime = apptInfo.iStartTime; |
221 id.mInstanceTime = apptInfo.iStartTime; |
217 apptInfo.iId = id; |
222 apptInfo.iId = id; |
218 apptInfo.iAllDay = 0; |
223 apptInfo.iAllDay = 0; |
219 apptInfo.iColor = 0xffff; |
224 apptInfo.iColor = 0xffff; |
220 |
225 |
221 int startSlot, endSlot, columnIdx, columns; |
226 int startSlot, endSlot, columnIdx, columns; |
222 mInfo->GetLocation( apptInfo, startSlot, endSlot, columnIdx, columns ); |
227 mInfo->GetLocation(apptInfo, startSlot, endSlot, columnIdx, columns); |
223 |
228 |
224 |
229 // 2. Set timed event's geometry |
225 //2. set timed event's geometry |
230 qreal eventStartX(mLayoutValues.eventAreaX); |
226 qreal eventStartX(mLayoutValues.eventAreaX ); |
|
227 qreal eventStartY(0.0); |
231 qreal eventStartY(0.0); |
228 qreal eventWidth(mLayoutValues.eventAreaWidth); |
232 qreal eventWidth(mLayoutValues.eventAreaWidth); |
229 qreal eventHeight(0.0); |
233 qreal eventHeight(0.0); |
230 |
234 |
231 //event's startY/height |
235 // Event's startY/height |
232 eventStartY = startSlot * mLayoutValues.slotHeight; |
236 eventStartY = startSlot * mLayoutValues.slotHeight; |
233 eventHeight = (endSlot - startSlot) * mLayoutValues.slotHeight; |
237 eventHeight = (endSlot - startSlot) * mLayoutValues.slotHeight; |
234 |
238 |
235 //event's startX/width |
239 // Event's startX/width |
236 eventWidth /= columns; |
240 eventWidth /= columns; |
237 |
241 |
238 //In case when eventWidth will be smaller then 3.0un we need to |
242 // In case when eventWidth will be smaller then KCalenMinBubbleWidth [un] |
239 //make spacings between events smaller. |
243 // spacings between events should be smaller. |
240 //Check whether it's possible to shring them so the bubbles |
244 // Check whether it's possible to shrink them so the bubbles width |
241 //width can stay at 3.0un (time stripe + frame margins). |
245 // can stay at KCalenMinBubbleWidth [un] (time stripe + frame margins). |
242 qreal minWidth = 3.0 * mLayoutValues.unitInPixels; |
246 qreal minWidth = KCalenMinBubbleWidth * mLayoutValues.unitInPixels; |
243 if(eventWidth - mLayoutValues.eventMargin < minWidth){ |
247 if (eventWidth - mLayoutValues.eventMargin < minWidth) { |
244 |
248 |
245 //Calculate new margin value |
249 // Calculate new margin value |
246 //from totalMarginSpace we need to subtract |
250 // from totalMarginSpace we need to subtract |
247 //mLayoutValues.eventMargin because first margin is always 1.5un |
251 // mLayoutValues.eventMargin because first margin is always 1.5un |
248 qreal totalMarginSpace = mLayoutValues.eventAreaWidth - minWidth * columns - mLayoutValues.eventMargin; |
252 qreal totalMarginSpace = mLayoutValues.eventAreaWidth - minWidth |
|
253 * columns - mLayoutValues.eventMargin; |
249 qreal newMarginValue = totalMarginSpace / (columns - 1); |
254 qreal newMarginValue = totalMarginSpace / (columns - 1); |
250 |
255 |
251 //check if we managed to pack all the events into space we have |
256 // Check if we managed to pack all the events into space we have |
252 if(newMarginValue > 0){ |
257 if (newMarginValue > 0) { |
253 |
|
254 eventWidth = minWidth; |
258 eventWidth = minWidth; |
255 } |
259 } |
256 else{ |
260 else { |
257 //there's not enough space |
261 // There's not enough space |
258 //new minWidth it's 1.5un (time stripe only) |
262 // New minWidth is KCalenTimeStripWidth [un] (time stripe only) |
259 minWidth = 1.5 * mLayoutValues.unitInPixels; |
263 minWidth = KCalenTimeStripWidth * mLayoutValues.unitInPixels; |
260 totalMarginSpace = mLayoutValues.eventAreaWidth - minWidth * columns - mLayoutValues.eventMargin; |
264 totalMarginSpace = mLayoutValues.eventAreaWidth - minWidth * columns |
|
265 - mLayoutValues.eventMargin; |
261 newMarginValue = totalMarginSpace / (columns - 1); |
266 newMarginValue = totalMarginSpace / (columns - 1); |
262 eventWidth = minWidth; |
267 eventWidth = minWidth; |
263 } |
268 } |
264 |
269 |
265 //First column margin should be always 1.5un (mLayoutValues.eventMargin) |
270 //First column margin should be always 1.5un (mLayoutValues.eventMargin) |
266 eventStartX += columnIdx * (eventWidth + newMarginValue) + mLayoutValues.eventMargin; |
271 eventStartX += columnIdx * (eventWidth + newMarginValue) + mLayoutValues.eventMargin; |
267 } |
272 } |
268 else{ |
273 else { |
269 //add margins between the event |
274 // Add margins between the event |
270 eventStartX += columnIdx * eventWidth + mLayoutValues.eventMargin; |
275 eventStartX += columnIdx * eventWidth + mLayoutValues.eventMargin; |
271 eventWidth -= mLayoutValues.eventMargin; |
276 eventWidth -= mLayoutValues.eventMargin; |
272 } |
277 } |
273 |
278 |
274 QRectF eventGeometry( eventStartX, eventStartY, eventWidth, eventHeight ); |
279 QRectF eventGeometry(eventStartX, eventStartY, eventWidth, eventHeight); |
275 item->setGeometry(eventGeometry);} |
280 item->setGeometry(eventGeometry); |
276 |
281 } |
277 |
282 |
278 // ----------------------------------------------------------------------------- |
283 |
279 // updateAllDayEventGeometry() |
284 /*! |
280 // Updates geometry of a timed event. |
285 \brief Set size and position of singe all-day event widget (bubble) |
281 // ----------------------------------------------------------------------------- |
286 \a item bubble widget |
282 // |
287 \a index pointing item data in model |
283 void CalenDayContainer::updateAllDayEventGeometry(HbAbstractViewItem *item, |
288 */ |
284 const QModelIndex &index) |
289 void CalenDayContainer::updateAllDayEventGeometry( |
285 { |
290 HbAbstractViewItem *item, |
286 //safety check |
291 const QModelIndex &index) |
287 if ( !mInfo ) { |
292 { |
288 return; |
293 // Safety check |
289 } |
294 if (!mInfo) { |
290 |
295 return; |
291 QVariant variant = index.data( CalenDayEntry ); |
296 } |
292 AgendaEntry entry = variant.value<AgendaEntry>(); |
297 |
293 |
298 QVariant variant = index.data(CalenDayEntry); |
294 //1. get 'virtual' event position from DayInfo |
299 AgendaEntry entry = variant.value<AgendaEntry> (); |
295 //TODO: k.g.: Day Info should store model index instead of keeping redundant data |
300 |
296 SCalenApptInfo apptInfo; |
301 // 1. Get 'virtual' event position from DayInfo |
297 apptInfo.iIndex = index; |
302 SCalenApptInfo apptInfo; |
298 |
303 apptInfo.iIndex = index; |
299 |
304 |
300 QDateTime start; |
305 QDateTime start; |
301 QDateTime end; |
306 QDateTime end; |
302 QDateTime currentDate; |
307 QDateTime currentDate; |
303 currentDate = static_cast<const CalenDayModel*>(index.model())->modelDate(); |
308 currentDate |
304 CalenDayUtils::instance()->getEventValidStartEndTime( start, end, entry, |
309 = static_cast<const CalenDayModel*> (index.model())->modelDate(); |
305 currentDate ); |
310 CalenDayUtils::instance()->getEventValidStartEndTime(start, end, entry, |
|
311 currentDate); |
306 apptInfo.iStartTime = start; |
312 apptInfo.iStartTime = start; |
307 apptInfo.iEndTime = end; |
313 apptInfo.iEndTime = end; |
308 |
314 |
309 TCalenInstanceId id = TCalenInstanceId::nullInstanceId(); |
315 TCalenInstanceId id = TCalenInstanceId::nullInstanceId(); |
310 id.mEntryLocalUid = index.row(); //index.row() - temporary ID |
316 id.mEntryLocalUid = index.row(); //index.row() - temporary ID |
311 id.mInstanceTime = apptInfo.iStartTime; |
317 id.mInstanceTime = apptInfo.iStartTime; |
312 apptInfo.iId = id; |
318 apptInfo.iId = id; |
313 apptInfo.iAllDay = true; |
319 apptInfo.iAllDay = true; |
314 apptInfo.iColor = 0xffff; |
320 apptInfo.iColor = 0xffff; |
315 |
321 |
316 int startSlot, endSlot, columnIdx, columns; |
322 int startSlot, endSlot, columnIdx, columns; |
317 mInfo->GetLocation( apptInfo, startSlot, endSlot, columnIdx, columns ); |
323 mInfo->GetLocation(apptInfo, startSlot, endSlot, columnIdx, columns); |
318 |
324 |
319 //2. set timed event's geometry |
325 // 2. Set timed event's geometry |
320 qreal eventStartX(0.0); |
326 qreal eventStartX(0.0); |
321 qreal eventStartY(0.0); |
327 qreal eventStartY(0.0); |
322 qreal eventWidth(mLayoutValues.eventAreaX); |
328 qreal eventWidth(mLayoutValues.eventAreaX); |
323 qreal eventHeight = (endSlot - startSlot) * mLayoutValues.slotHeight; |
329 qreal eventHeight = (endSlot - startSlot) * mLayoutValues.slotHeight; |
324 |
330 |
325 |
331 // Event's startX/width |
326 //event's startX/width |
332 if (columns > 1) { |
327 if ( columns > 1 ) { |
333 eventWidth /= columns; |
328 eventWidth /= columns; |
334 eventStartX += columnIdx * eventWidth + mLayoutValues.eventMargin; |
329 eventStartX += columnIdx * eventWidth + mLayoutValues.eventMargin; |
335 // Add margins between the event |
330 //add margins between the event |
336 eventWidth -= mLayoutValues.eventMargin; |
331 eventWidth -= mLayoutValues.eventMargin; |
337 } |
332 } else { |
338 else { |
333 eventStartX += mLayoutValues.eventMargin; |
339 eventStartX += mLayoutValues.eventMargin; |
334 eventWidth -= mLayoutValues.eventMargin; |
340 eventWidth -= mLayoutValues.eventMargin; |
335 } |
341 } |
336 |
342 |
337 QRectF eventGeometry( eventStartX, eventStartY, eventWidth, eventHeight ); |
343 QRectF eventGeometry(eventStartX, eventStartY, eventWidth, eventHeight); |
338 item->setGeometry(eventGeometry); |
344 item->setGeometry(eventGeometry); |
339 |
345 } |
340 } |
346 |
341 |
347 |
342 |
348 /*! |
343 // ----------------------------------------------------------------------------- |
349 \brief Gets event layout values |
344 // movingBackwards() |
350 \a layoutValues structure to be filled with layout data |
345 // |
351 */ |
346 // ----------------------------------------------------------------------------- |
|
347 // |
|
348 void CalenDayContainer::getTimedEventLayoutValues(LayoutValues& layoutValues) |
352 void CalenDayContainer::getTimedEventLayoutValues(LayoutValues& layoutValues) |
349 { |
353 { |
350 // get the width of content area |
354 // Get the width of content area |
351 qreal contentWidth = CalenDayUtils::instance()->contentWidth(); |
355 qreal contentWidth = CalenDayUtils::instance()->contentWidth(); |
352 //1.time column width -> eventAreaX[out] |
356 |
|
357 // 1. Time column width -> eventAreaX[out] |
353 HbStyle style; |
358 HbStyle style; |
354 HbDeviceProfile deviceProfile; |
359 HbDeviceProfile deviceProfile; |
355 layoutValues.unitInPixels = deviceProfile.unitValue(); |
360 layoutValues.unitInPixels = deviceProfile.unitValue(); |
356 |
361 |
357 if ( mInfo && mInfo->AlldayCount()) |
362 if (mInfo && mInfo->AlldayCount()) { |
358 { // 9.5 -> all-day area width |
363 layoutValues.eventAreaX = KCalenAllDayEventArea * contentWidth; |
359 layoutValues.eventAreaX = 9.5 * layoutValues.unitInPixels; |
364 } |
360 } |
365 else { |
361 else |
366 layoutValues.eventAreaX = 0; |
362 { |
367 } |
363 layoutValues.eventAreaX = 0; |
368 |
364 } |
369 // 2. event area width -> eventAreaWidth[out] |
365 |
|
366 //2. event area width -> eventAreaWidth[out] |
|
367 qreal emptyRightColumnWidth(0.0); |
370 qreal emptyRightColumnWidth(0.0); |
368 emptyRightColumnWidth = 6.0 * layoutValues.unitInPixels; //pix (according to UI spec) |
371 emptyRightColumnWidth = KCalenEmptyRightColumnWidth |
369 layoutValues.eventAreaWidth = contentWidth - emptyRightColumnWidth - layoutValues.eventAreaX ; |
372 * layoutValues.unitInPixels; |
370 //3. margins between the overlapping events -> eventMargin[out] |
373 layoutValues.eventAreaWidth = contentWidth - emptyRightColumnWidth |
371 layoutValues.eventMargin = 1.5 * layoutValues.unitInPixels; |
374 - layoutValues.eventAreaX; |
372 //4. half-hour slot'h height -> slotHeight[out] |
375 |
373 //curent slot height corresponds to half an hour |
376 // 3. margins between the overlapping events -> eventMargin[out] |
374 layoutValues.slotHeight = |
377 layoutValues.eventMargin = KCalenSpaceBeetwenEvents |
375 CalenDayUtils::instance()->hourElementHeight() / 2; |
378 * layoutValues.unitInPixels; |
376 |
379 |
377 // 8.2 un (min. touchable event) from layout guide |
380 // 4. half-hour slot'h height -> slotHeight[out] |
378 layoutValues.maxColumns = layoutValues.eventAreaWidth / (8.2 * layoutValues.unitInPixels); |
381 layoutValues.slotHeight = CalenDayUtils::instance()->hourElementHeight() |
|
382 / KCalenSlotsInHour; |
|
383 |
|
384 // check if we should create absorber over some overlapping region |
|
385 layoutValues.maxColumns = layoutValues.eventAreaWidth |
|
386 / (KCalenMinTouchableEventWidth * layoutValues.unitInPixels); |
|
387 } |
|
388 |
|
389 |
|
390 /*! |
|
391 \brief Sets day's info structure to the container. |
|
392 \a dayInfo day's info data |
|
393 |
|
394 \sa CalenDayInfo, CalenDayContainer::dayInfo |
|
395 */ |
|
396 void CalenDayContainer::setDayInfo(CalenDayInfo* dayInfo) |
|
397 { |
|
398 mInfo = dayInfo; |
|
399 } |
|
400 |
|
401 /*! |
|
402 \brief It return pointer to info structure of container. |
|
403 |
|
404 \sa CalenDayInfo, CalenDayContainer::setDayInfo |
|
405 */ |
|
406 CalenDayInfo* CalenDayContainer::dayInfo() |
|
407 { |
|
408 return mInfo; |
|
409 } |
|
410 |
|
411 /*! |
|
412 \brief Sets date to the container. |
|
413 Changes according to model which is connected to given view. |
|
414 |
|
415 \a date Date of container |
|
416 */ |
|
417 void CalenDayContainer::setDate(const QDate &date) |
|
418 { |
|
419 mDate = date; |
379 } |
420 } |
380 |
421 |
381 // ----------------------------------------------------------------------------- |
422 // ----------------------------------------------------------------------------- |
382 // setDayInfo() |
423 // date() |
383 // Sets day's info structer to the container. |
424 // Returns date of the container. |
384 // ----------------------------------------------------------------------------- |
425 // ----------------------------------------------------------------------------- |
385 // |
426 // |
386 void CalenDayContainer::setDayInfo( CalenDayInfo* dayInfo ) |
427 /*! |
387 { |
428 \brief Returns date of the container. |
388 mInfo = dayInfo; |
429 |
389 } |
430 \sa date Date of container |
390 |
431 */ |
391 // ----------------------------------------------------------------------------- |
432 const QDate &CalenDayContainer::date() const |
392 // orientationChanged() |
433 { |
393 // Slot handles layout switch. |
434 return mDate; |
394 // ----------------------------------------------------------------------------- |
435 } |
395 // |
436 |
|
437 /*! |
|
438 \brief Slot handles layout switch. |
|
439 \a orientation current device orientation |
|
440 */ |
396 void CalenDayContainer::orientationChanged(Qt::Orientation orientation) |
441 void CalenDayContainer::orientationChanged(Qt::Orientation orientation) |
397 { |
442 { |
398 getTimedEventLayoutValues(mLayoutValues); |
443 getTimedEventLayoutValues(mLayoutValues); |
399 |
444 |
400 Q_UNUSED( orientation ) |
445 Q_UNUSED( orientation ) |
401 QList<HbAbstractViewItem *> items = this->items(); |
446 QList<HbAbstractViewItem *> items = this->items(); |
402 int count(items.count()); |
447 int count(items.count()); |
403 for (int i = 0; i < count; i++) { |
448 for (int i = 0; i < count; i++) { |
404 QModelIndex modelIndex = items[i]->modelIndex(); |
449 QModelIndex modelIndex = items[i]->modelIndex(); |
405 if (modelIndex.isValid()) { |
450 if (modelIndex.isValid()) { |
406 QVariant variant = modelIndex.data(CalenDayEntry); |
451 QVariant variant = modelIndex.data(CalenDayEntry); |
407 AgendaEntry entry = variant.value<AgendaEntry> (); |
452 AgendaEntry entry = variant.value<AgendaEntry> (); |
408 if (entry.isTimedEntry()) { |
453 if (entry.isTimedEntry() && !CalenAgendaUtils::isAlldayEvent(entry)) { |
409 updateTimedEventGeometry(items[i], modelIndex); |
454 updateTimedEventGeometry(items[i], modelIndex); |
410 } |
455 } |
411 } |
456 else |
412 } |
457 if (CalenAgendaUtils::isAlldayEvent(entry)) { |
413 |
458 updateAllDayEventGeometry(items[i], modelIndex); |
|
459 } |
|
460 } |
|
461 } |
|
462 |
414 createTouchEventAbsorbers(); |
463 createTouchEventAbsorbers(); |
415 } |
464 } |
416 |
465 |
417 // ----------------------------------------------------------------------------- |
466 |
418 // createTouchEventAbsorbers() |
467 /*! |
419 // Creates absorbers which prevent touching to small items |
468 \brief Creates absorbers which prevent touching to small items |
420 // ----------------------------------------------------------------------------- |
469 According to UI spec items smaller than 8.2 un are untouchable |
421 // |
470 */ |
422 void CalenDayContainer::createTouchEventAbsorbers() |
471 void CalenDayContainer::createTouchEventAbsorbers() |
423 { |
472 { |
424 // remove absorbers if exist |
473 // remove absorbers if exist |
425 if (mAbsorbers.count()) |
474 if (mAbsorbers.count()) { |
426 { |
475 qDeleteAll(mAbsorbers); |
427 qDeleteAll(mAbsorbers); |
476 mAbsorbers.clear(); |
428 mAbsorbers.clear(); |
477 } |
429 } |
478 |
430 |
479 // Create absorber for all-day events |
431 const QList<CalenTimeRegion>& regionList = mInfo->RegionList(); |
480 Qt::Orientation orientation = CalenDayUtils::instance()->orientation(); |
432 |
481 int allDayCount = mInfo->AlldayCount(); |
433 for(int i=0; i < regionList.count(); i++) |
482 |
434 { |
483 if ((orientation == Qt::Vertical |
435 if(regionList[i].iColumns.count() > mLayoutValues.maxColumns ) |
484 && allDayCount > KCalenTouchableAllDayEventsCountPortrait) |
436 { |
485 || (orientation == Qt::Horizontal |
437 TouchEventAbsorber* absorber = |
486 && allDayCount > KCalenTouchableAllDayEventsCountLandscape)) { |
438 crateAbsorberBetweenSlots(regionList[i].iStartSlot, regionList[i].iEndSlot); |
487 TouchEventAbsorber* absorber = crateAbsorberBetweenSlots(0, 0, true); |
439 |
488 mAbsorbers.append(absorber); |
440 mAbsorbers.append(absorber); |
489 } |
441 } |
490 |
442 } |
491 // Create absorbers for timed events |
443 |
492 const QList<CalenTimeRegion>& regionList = mInfo->RegionList(); |
444 } |
493 for (int i = 0; i < regionList.count(); i++) { |
445 |
494 if (regionList[i].iColumns.count() > mLayoutValues.maxColumns) { |
446 // ----------------------------------------------------------------------------- |
495 TouchEventAbsorber* absorber = crateAbsorberBetweenSlots( |
447 // crateAbsorberBetweenSlots() |
496 regionList[i].iStartSlot, regionList[i].iEndSlot, false); |
448 // Creates single absorber in given location |
497 |
449 // ----------------------------------------------------------------------------- |
498 mAbsorbers.append(absorber); |
450 // |
499 } |
451 TouchEventAbsorber *CalenDayContainer::crateAbsorberBetweenSlots |
500 } |
452 (int startSlot, int endSlot) |
501 } |
|
502 |
|
503 |
|
504 /*! |
|
505 \brief Creates single absorber in given location |
|
506 \a startSlot absorber area starts from there |
|
507 \a endSlot absobrber area ends here |
|
508 \a forAllDayEvents if true absorber in all-day events area is created |
|
509 */ |
|
510 TouchEventAbsorber *CalenDayContainer::crateAbsorberBetweenSlots( |
|
511 int startSlot, |
|
512 int endSlot, |
|
513 bool forAllDayEvents) |
453 { |
514 { |
454 TouchEventAbsorber *absorber = new TouchEventAbsorber(this); |
515 TouchEventAbsorber *absorber = new TouchEventAbsorber(this); |
455 absorber->setZValue(1000); |
516 absorber->setZValue(1000); |
456 absorber->setVisible(true); |
517 absorber->setVisible(true); |
457 |
518 if (!forAllDayEvents) { |
458 absorber->setGeometry( mLayoutValues.eventAreaX, // x |
519 absorber->setGeometry(mLayoutValues.eventAreaX, // x |
459 startSlot * mLayoutValues.slotHeight, // y |
520 startSlot * mLayoutValues.slotHeight, // y |
460 mLayoutValues.eventAreaWidth, // w |
521 mLayoutValues.eventAreaWidth, // w |
461 (endSlot-startSlot) * mLayoutValues.slotHeight ); // h |
522 (endSlot - startSlot) * mLayoutValues.slotHeight); // h |
462 |
523 } |
|
524 else { |
|
525 absorber->setGeometry(0, 0, mLayoutValues.eventAreaX, |
|
526 KCalenHoursInDay * KCalenSlotsInHour * mLayoutValues.slotHeight); |
|
527 } |
|
528 |
463 return absorber; |
529 return absorber; |
464 } |
530 } |
465 |
531 |
466 |
532 |
467 // ----------------------------------------------------------------------------- |
533 /*! |
468 // TouchEventAbsorber::gestureEvent() |
534 \brief Handles tap event on overlapping area |
469 // Handles tap event on overlapping area (currently it leads to Agenda View - |
535 Currently it leads to Agenda View - as described in UI spec |
470 // as described in UI spec) |
536 \a event qt gesture event |
471 // ----------------------------------------------------------------------------- |
537 */ |
472 // |
|
473 void TouchEventAbsorber::gestureEvent(QGestureEvent *event) |
538 void TouchEventAbsorber::gestureEvent(QGestureEvent *event) |
474 { |
539 { |
475 QTapGesture *tapGesture = qobject_cast<QTapGesture*> (event->gesture( |
540 QTapGesture *tapGesture = qobject_cast<QTapGesture*> (event->gesture( |
476 Qt::TapGesture)); |
541 Qt::TapGesture)); |
477 |
542 |
478 if (tapGesture && tapGesture->state() == Qt::GestureFinished) |
543 if (tapGesture && tapGesture->state() == Qt::GestureFinished) { |
479 { |
|
480 CalenDayView* dayView = static_cast<CalenDayView*> |
544 CalenDayView* dayView = static_cast<CalenDayView*> |
481 (CalenDayUtils::instance()->mainWindow()->currentView()); |
545 (CalenDayUtils::instance()->mainWindow()->currentView()); |
482 |
546 |
483 dayView->changeView(ECalenAgendaView); |
547 dayView->changeView(ECalenAgendaView); |
484 } |
548 } |
485 } |
549 } |
486 |
550 |
487 // ----------------------------------------------------------------------------- |
551 /*! |
488 // TouchEventAbsorber() |
552 \brief Constructor |
489 // default ctor |
553 */ |
490 // ----------------------------------------------------------------------------- |
554 TouchEventAbsorber::TouchEventAbsorber(QGraphicsItem *parent) : |
491 // |
555 HbWidget(parent) |
492 TouchEventAbsorber::TouchEventAbsorber(QGraphicsItem *parent) : HbWidget(parent) |
|
493 { |
556 { |
494 #ifdef _DEBUG |
557 #ifdef _DEBUG |
495 setFlag(QGraphicsItem::ItemHasNoContents, false); |
558 setFlag(QGraphicsItem::ItemHasNoContents, false); |
496 #endif |
559 #endif |
497 grabGesture(Qt::TapGesture); |
560 grabGesture(Qt::TapGesture); |
498 } |
561 } |
499 |
562 |
500 // ----------------------------------------------------------------------------- |
563 |
501 // TouchEventAbsorber() |
564 /*! |
502 // default dtor |
565 \brief Destructor |
503 // ----------------------------------------------------------------------------- |
566 |
504 // |
567 Sets container initial geometry, creates hours area widgets. |
|
568 */ |
505 TouchEventAbsorber::~TouchEventAbsorber() |
569 TouchEventAbsorber::~TouchEventAbsorber() |
506 { |
570 { |
507 |
571 |
508 } |
572 } |
509 |
573 |
510 // ----------------------------------------------------------------------------- |
574 |
511 // TouchEventAbsorber::paint() |
575 /*! |
512 // used for debugging purposes to see absorbers areas |
576 \brief Used for debugging purposes to see absorbers areas |
513 // ----------------------------------------------------------------------------- |
577 Not active in release builds! |
514 // |
578 |
|
579 */ |
515 #ifdef _DEBUG |
580 #ifdef _DEBUG |
516 void TouchEventAbsorber::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, |
581 void TouchEventAbsorber::paint( |
517 QWidget *widget) |
582 QPainter *painter, |
518 { |
583 const QStyleOptionGraphicsItem *option, |
519 Q_UNUSED(option) |
584 QWidget *widget) |
520 Q_UNUSED(widget) |
585 { |
521 |
586 Q_UNUSED(option) |
522 painter->save(); |
587 Q_UNUSED(widget) |
523 QPen pen; |
588 |
524 pen.setWidth(2); |
589 painter->save(); |
525 pen.setColor(Qt::red); |
590 QPen pen; |
526 painter->setPen(pen); |
591 pen.setWidth(2); |
527 painter->drawRect(boundingRect()); |
592 pen.setColor(Qt::red); |
528 painter->restore(); |
593 painter->setPen(pen); |
|
594 painter->drawRect(boundingRect()); |
|
595 painter->restore(); |
529 } |
596 } |
530 #endif |
597 #endif |
531 // End of File |
598 // End of File |