|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <HbInstance> |
|
19 |
|
20 #include "hsdomainmodeldatastructures.h" |
|
21 #include "hspage.h" |
|
22 #include "hspagetoucharea.h" |
|
23 #include "hspagenewwidgetlayout.h" |
|
24 #include "hsscene.h" |
|
25 #include "hswidgethost.h" |
|
26 #include "hswallpaper.h" |
|
27 #include "hswidgetpositioningonwidgetadd.h" |
|
28 #include "hswidgetpositioningonorientationchange.h" |
|
29 #include "hsconfiguration.h" |
|
30 #include "hsgui.h" |
|
31 |
|
32 /*! |
|
33 \class HsPage |
|
34 \ingroup group_hsdomainmodel |
|
35 \brief Represents a page in the framework. |
|
36 HsPage contains group of widgets. HsPage can have a wallpaper. |
|
37 */ |
|
38 |
|
39 /*! |
|
40 Constructor. |
|
41 |
|
42 \a parent Owner. |
|
43 \a aFlags Window flags. |
|
44 */ |
|
45 HsPage::HsPage(QObject* parent) |
|
46 : QObject(parent), |
|
47 mDatabaseId(-1), |
|
48 mWallpaper(0), |
|
49 mRemovable(true), |
|
50 mPageMargin(0.0) |
|
51 { |
|
52 |
|
53 //Page margin |
|
54 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
|
55 connect(HsConfiguration::instance(), SIGNAL(propertyChanged(QString)), SLOT(onPageMarginChanged(QString))); |
|
56 } |
|
57 |
|
58 /*! |
|
59 Destructor. |
|
60 */ |
|
61 HsPage::~HsPage() |
|
62 { |
|
63 delete mWallpaper; |
|
64 } |
|
65 |
|
66 /*! |
|
67 Returns the database id. |
|
68 */ |
|
69 int HsPage::databaseId() const |
|
70 { |
|
71 return mDatabaseId; |
|
72 } |
|
73 |
|
74 /*! |
|
75 Sets the database id to \a id. |
|
76 */ |
|
77 void HsPage::setDatabaseId(int id) |
|
78 { |
|
79 mDatabaseId = id; |
|
80 } |
|
81 |
|
82 |
|
83 |
|
84 /*! |
|
85 Loads widgets. |
|
86 */ |
|
87 bool HsPage::load() |
|
88 { |
|
89 if (HSCONFIGURATION_GET(sceneType) == HsConfiguration::PageWallpapers) { |
|
90 mWallpaper = new HsPageWallpaper(this); |
|
91 } |
|
92 |
|
93 /* HsWidgetHost *widget = new HsWidgetHost(-1); |
|
94 mWidgets.append(widget); |
|
95 connectWidget(widget); |
|
96 widget->setPage(this); |
|
97 widget->setParentItem(this); |
|
98 widget->setPos(100, 100); |
|
99 widget->startWidget(); |
|
100 */ |
|
101 return true; |
|
102 } |
|
103 |
|
104 /*! |
|
105 Return wallpaper. |
|
106 */ |
|
107 HsWallpaper *HsPage::wallpaper() const |
|
108 { |
|
109 return mWallpaper; |
|
110 } |
|
111 /*! |
|
112 Add given existing \a widgetHost to a page. Returns true if successful |
|
113 */ |
|
114 bool HsPage::addExistingWidget(HsWidgetHost *widgetHost) |
|
115 { |
|
116 if (!widgetHost) { |
|
117 return false; |
|
118 } |
|
119 |
|
120 if (mWidgets.contains(widgetHost)) { |
|
121 return true; |
|
122 } |
|
123 |
|
124 if (!widgetHost->setPage(this)) { |
|
125 return false; |
|
126 } |
|
127 |
|
128 connectWidget(widgetHost); |
|
129 mWidgets << widgetHost; |
|
130 // widgetHost->setParentItem(this); |
|
131 |
|
132 return true; |
|
133 } |
|
134 |
|
135 /*! |
|
136 Remove given \a widgetHost from a page. Widget is not deleted. |
|
137 Returns true if successful |
|
138 */ |
|
139 bool HsPage::removeWidget(HsWidgetHost *widgetHost) |
|
140 { |
|
141 if (!widgetHost || !widgetHost->setPage(0)) { |
|
142 return false; |
|
143 } |
|
144 |
|
145 disconnectWidget(widgetHost); |
|
146 mWidgets.removeOne(widgetHost); |
|
147 // widgetHost->setParentItem(0); |
|
148 |
|
149 return true; |
|
150 } |
|
151 |
|
152 /*! |
|
153 Returns list of new widgets belonging to a page. Widgets which are |
|
154 not yet layouted are considered as new widgets. |
|
155 */ |
|
156 QList<HsWidgetHost *> HsPage::newWidgets() |
|
157 { |
|
158 return mNewWidgets; |
|
159 } |
|
160 |
|
161 /*! |
|
162 Adds new widget into a page. Returns true if successfull. |
|
163 */ |
|
164 bool HsPage::addNewWidget(HsWidgetHost* widgetHost, const QPointF &touchPoint) |
|
165 { |
|
166 Q_UNUSED(touchPoint) |
|
167 if (!widgetHost || mWidgets.contains(widgetHost)) { |
|
168 return false; |
|
169 } |
|
170 |
|
171 if (mNewWidgets.contains(widgetHost)) { |
|
172 return true; |
|
173 } |
|
174 |
|
175 HsWidgetPresentationData presentation; |
|
176 presentation.orientation = HsGui::instance()->orientation(); |
|
177 if (!widgetHost->getPresentation(presentation)) { |
|
178 presentation.orientation = HsGui::instance()->orientation(); |
|
179 presentation.setPos(QPointF()); |
|
180 presentation.zValue = 0; |
|
181 widgetHost->savePresentation(presentation); |
|
182 } |
|
183 |
|
184 // widgetHost->hide(); |
|
185 // widgetHost->setPos(presentation.x, presentation.y); |
|
186 // widgetHost->setZValue(presentation.zValue); |
|
187 |
|
188 connectWidget(widgetHost); |
|
189 mNewWidgets << widgetHost; |
|
190 |
|
191 return true; |
|
192 } |
|
193 |
|
194 /*! |
|
195 Layouts all the new widgets |
|
196 */ |
|
197 void HsPage::layoutNewWidgets() |
|
198 { |
|
199 if (mNewWidgets.isEmpty()) { |
|
200 return; |
|
201 } |
|
202 |
|
203 updateZValues(); |
|
204 HsWidgetHost *widget = 0; |
|
205 for (int i = 0; i < mNewWidgets.count(); ++i) { |
|
206 widget = mNewWidgets.at(i); |
|
207 //Not used in mock newWidgetLayout->addItem(widget); |
|
208 widget->setPage(this); |
|
209 // widget->setParentItem(this); |
|
210 widget->showWidget(); |
|
211 // widget->show(); |
|
212 } |
|
213 mWidgets << mNewWidgets; |
|
214 mNewWidgets.clear(); |
|
215 } |
|
216 |
|
217 /*! |
|
218 Clears new widgets list and resets layout. |
|
219 */ |
|
220 void HsPage::resetNewWidgets() |
|
221 { |
|
222 mNewWidgets.clear(); |
|
223 //setLayout(0); |
|
224 } |
|
225 |
|
226 /*! |
|
227 Remove page and all it's contained widgets from database |
|
228 */ |
|
229 bool HsPage::deleteFromDatabase() |
|
230 { |
|
231 //Not used in mock |
|
232 return true; |
|
233 } |
|
234 |
|
235 /*! |
|
236 Return list of widgets belonging to a page |
|
237 */ |
|
238 QList<HsWidgetHost *> HsPage::widgets() const |
|
239 { |
|
240 return mWidgets; |
|
241 } |
|
242 |
|
243 /*! |
|
244 Returns true if the page can be removed. Otherwise, |
|
245 returns false. |
|
246 */ |
|
247 bool HsPage::isRemovable() const |
|
248 { |
|
249 return mRemovable; |
|
250 } |
|
251 |
|
252 /*! |
|
253 Sets removable flag to \a removable. |
|
254 */ |
|
255 void HsPage::setRemovable(bool removable) |
|
256 { |
|
257 mRemovable = removable; |
|
258 } |
|
259 |
|
260 /*! |
|
261 Return true if page is default page. |
|
262 */ |
|
263 bool HsPage::isDefaultPage() const |
|
264 { |
|
265 return mDatabaseId == HSCONFIGURATION_GET(defaultPageId); |
|
266 } |
|
267 |
|
268 /*! |
|
269 Return true if page is active page. |
|
270 */ |
|
271 bool HsPage::isActivePage() const |
|
272 { |
|
273 return this == HsScene::instance()->activePage(); |
|
274 } |
|
275 |
|
276 /*! |
|
277 Create page into database and return instance of a new page. |
|
278 */ |
|
279 HsPage *HsPage::createInstance(const HsPageData &pageData) |
|
280 { |
|
281 Q_UNUSED(pageData); |
|
282 HsPage *page = new HsPage; |
|
283 return page; |
|
284 } |
|
285 |
|
286 /*! |
|
287 The widget is bounded in the rectangle which is smaller by PageMargin on all sides of page. |
|
288 */ |
|
289 QPointF HsPage::adjustedWidgetPosition(const QRectF &origWidgetRect) |
|
290 { |
|
291 QRectF widgetAreaRect = contentGeometry(); |
|
292 qreal widgetX = qBound(widgetAreaRect.left(), origWidgetRect.x(), widgetAreaRect.right() - origWidgetRect.width()); |
|
293 qreal widgetY = qBound(widgetAreaRect.top(), origWidgetRect.y(), widgetAreaRect.bottom() - origWidgetRect.height()); |
|
294 |
|
295 return QPointF(widgetX, widgetY); |
|
296 } |
|
297 |
|
298 /*! |
|
299 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
300 */ |
|
301 QRectF HsPage::contentGeometry() |
|
302 { |
|
303 return contentGeometry(HsGui::instance()->orientation()); |
|
304 } |
|
305 |
|
306 /*! |
|
307 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
308 */ |
|
309 QRectF HsPage::contentGeometry(Qt::Orientation orientation) |
|
310 { |
|
311 QRectF pageRect; |
|
312 //pageRect = rect(); |
|
313 |
|
314 if (orientation != HsGui::instance()->orientation()) { |
|
315 qreal width = pageRect.width(); |
|
316 qreal height = pageRect.height(); |
|
317 pageRect.setWidth(height); |
|
318 pageRect.setHeight(width); |
|
319 } |
|
320 |
|
321 //Take care of chrome in both orientation |
|
322 pageRect.setTop(64); |
|
323 |
|
324 //Shrink by page margins at each side |
|
325 return pageRect.adjusted(mPageMargin, mPageMargin, -mPageMargin, -mPageMargin); |
|
326 } |
|
327 |
|
328 /*! |
|
329 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
330 */ |
|
331 QRectF HsPage::contentRect() |
|
332 { |
|
333 return contentRect(HsGui::instance()->orientation()); |
|
334 } |
|
335 |
|
336 /*! |
|
337 Returns rect of rectangular where widgets are allowed to be placed in the page. |
|
338 */ |
|
339 QRectF HsPage::contentRect(Qt::Orientation orientation) |
|
340 { |
|
341 QRectF rect = contentGeometry(orientation); |
|
342 rect.moveTopLeft(QPointF(0,0)); |
|
343 return rect; |
|
344 } |
|
345 |
|
346 /*! |
|
347 Calls onShow() for contained widgets. |
|
348 */ |
|
349 void HsPage::showWidgets() |
|
350 { |
|
351 /* foreach (HsWidgetHost *widget, mWidgets) { |
|
352 if (widget->parentItem() == this) { |
|
353 widget->showWidget(); |
|
354 } |
|
355 } |
|
356 */ |
|
357 } |
|
358 |
|
359 /*! |
|
360 Calls onHide() for contained widgets. |
|
361 */ |
|
362 void HsPage::hideWidgets() |
|
363 { |
|
364 /* foreach (HsWidgetHost *widget, mWidgets) { |
|
365 if (widget->parentItem() == this) { |
|
366 widget->hideWidget(); |
|
367 } |
|
368 } |
|
369 */ |
|
370 } |
|
371 |
|
372 /*! |
|
373 Propagate online state to widgets. |
|
374 */ |
|
375 void HsPage::setOnline(bool online) |
|
376 { |
|
377 foreach (HsWidgetHost *widget, mNewWidgets) { |
|
378 widget->setOnline(online); |
|
379 } |
|
380 foreach (HsWidgetHost *widget, mWidgets) { |
|
381 widget->setOnline(online); |
|
382 } |
|
383 } |
|
384 |
|
385 /*! |
|
386 Update widgets z-values and persist those. Active widget has top most |
|
387 z-value. |
|
388 */ |
|
389 void HsPage::updateZValues() |
|
390 { |
|
391 int z = 0; |
|
392 |
|
393 /*if (!mWidgets.isEmpty()) { |
|
394 QMultiMap<qreal, HsWidgetHost *> map; |
|
395 foreach (HsWidgetHost *widget, mWidgets) { |
|
396 map.insert(widget->zValue(), widget); |
|
397 } |
|
398 |
|
399 QList<HsWidgetHost *> sortedWidgets = map.values(); |
|
400 |
|
401 HsWidgetHost *activeWidget = HsScene::instance()->activeWidget(); |
|
402 if (sortedWidgets.contains(activeWidget)) { |
|
403 sortedWidgets.removeOne(activeWidget); |
|
404 sortedWidgets.append(activeWidget); |
|
405 } |
|
406 |
|
407 foreach (HsWidgetHost *widget, sortedWidgets) { |
|
408 widget->setZValue(z++); |
|
409 widget->savePresentation(); |
|
410 } |
|
411 } |
|
412 |
|
413 if (!mNewWidgets.isEmpty()) { |
|
414 foreach (HsWidgetHost *widget, mNewWidgets) { |
|
415 widget->setZValue(z++); |
|
416 widget->savePresentation(); |
|
417 } |
|
418 } |
|
419 */ |
|
420 } |
|
421 |
|
422 /*! |
|
423 Return this page's index. |
|
424 */ |
|
425 int HsPage::pageIndex() |
|
426 { |
|
427 return HsScene::instance()->pages().indexOf(this); |
|
428 } |
|
429 |
|
430 /*! |
|
431 Utility to connect widget signals to page. |
|
432 */ |
|
433 void HsPage::connectWidget(HsWidgetHost *widget) |
|
434 { |
|
435 connect(widget, SIGNAL(finished()), SLOT(onWidgetFinished())); |
|
436 connect(widget, SIGNAL(faulted()), SLOT(onWidgetFaulted())); |
|
437 connect(widget, SIGNAL(resized()), SLOT(onWidgetResized())); |
|
438 connect(widget, SIGNAL(available()), SLOT(onWidgetAvailable())); |
|
439 connect(widget, SIGNAL(unavailable()), SLOT(onWidgetUnavailable())); |
|
440 } |
|
441 /*! |
|
442 Disconnect widget signals from page |
|
443 */ |
|
444 void HsPage::disconnectWidget(HsWidgetHost *widget) |
|
445 { |
|
446 widget->disconnect(this); |
|
447 } |
|
448 /*! |
|
449 Disconnect and remove widget |
|
450 */ |
|
451 void HsPage::onWidgetFinished() |
|
452 { |
|
453 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
454 |
|
455 // It can be in new widget list if we haven't layouted it yet |
|
456 // or layouted new widget and widget list |
|
457 if (!mNewWidgets.removeOne(widget)) { |
|
458 mWidgets.removeOne(widget); |
|
459 } |
|
460 |
|
461 disconnectWidget(widget); |
|
462 widget->remove(); |
|
463 } |
|
464 /*! |
|
465 Remove widget if it faulted |
|
466 */ |
|
467 void HsPage::onWidgetFaulted() |
|
468 { |
|
469 onWidgetFinished(); |
|
470 } |
|
471 |
|
472 /*! |
|
473 Calculates new widget position on page when widget size changes. If page has layout then there are new widgets |
|
474 and we use layout to calculate new widget positions. |
|
475 */ |
|
476 void HsPage::onWidgetResized() |
|
477 { |
|
478 /* if ( !layout() ) { |
|
479 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
480 widget->setPos(adjustedWidgetPosition(widget->geometry())); |
|
481 } else { |
|
482 layout()->invalidate(); |
|
483 } |
|
484 */ |
|
485 } |
|
486 /*! |
|
487 Show widget if it came available |
|
488 */ |
|
489 void HsPage::onWidgetAvailable() |
|
490 { |
|
491 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
492 |
|
493 mUnavailableWidgets.removeOne(widget); |
|
494 mWidgets.append(widget); |
|
495 |
|
496 // widget->setParentItem(this); |
|
497 widget->startWidget(isActivePage()); |
|
498 // widget->show(); |
|
499 } |
|
500 /*! |
|
501 Update internal bookkeeping and hide widget |
|
502 */ |
|
503 void HsPage::onWidgetUnavailable() |
|
504 { |
|
505 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
506 |
|
507 if (mWidgets.contains(widget)) { |
|
508 mWidgets.removeOne(widget); |
|
509 } else if (mNewWidgets.contains(widget)) { |
|
510 mNewWidgets.removeOne(widget); |
|
511 } else { |
|
512 return; |
|
513 } |
|
514 |
|
515 mUnavailableWidgets.append(widget); |
|
516 |
|
517 /* widget->hide(); |
|
518 widget->setParentItem(0); |
|
519 */ |
|
520 } |
|
521 |
|
522 /*! |
|
523 Run positioning algorithm for widgets which don't have position on |
|
524 target orientation. Otherwise set orientation positions for widgets. |
|
525 */ |
|
526 void HsPage::onOrientationChanged(Qt::Orientation orientation) |
|
527 { |
|
528 Q_UNUSED(orientation) |
|
529 } |
|
530 |
|
531 void HsPage::onPageMarginChanged(const QString &value) |
|
532 { |
|
533 if (value == "pageMargin") { |
|
534 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
|
535 |
|
536 if (!mWidgets.isEmpty()) { |
|
537 foreach (HsWidgetHost *widget, mWidgets) { |
|
538 // widget->setPos(adjustedWidgetPosition(widget->geometry())); |
|
539 widget->savePresentation(); |
|
540 } |
|
541 } |
|
542 |
|
543 if (!mNewWidgets.isEmpty()) { |
|
544 foreach (HsWidgetHost *widget, mNewWidgets) { |
|
545 // widget->setPos(adjustedWidgetPosition(widget->geometry())); |
|
546 widget->savePresentation(); |
|
547 } |
|
548 } |
|
549 } |
|
550 } |
|
551 |
|
552 HsPageVisual *HsPage::visual()const |
|
553 { |
|
554 return 0; |
|
555 } |