41 Constructor. |
44 Constructor. |
42 |
45 |
43 \a parent Owner. |
46 \a parent Owner. |
44 \a aFlags Window flags. |
47 \a aFlags Window flags. |
45 */ |
48 */ |
46 HsPage::HsPage(QGraphicsItem* parent) |
49 HsPage::HsPage(QObject* parent) |
47 : HbWidget(parent), |
50 : QObject(parent), |
48 mDatabaseId(-1), |
51 mDatabaseId(-1), |
|
52 mPageVisual(new HsPageVisual), |
49 mWallpaper(0), |
53 mWallpaper(0), |
50 mRemovable(true), |
54 mRemovable(true), |
51 mTouchArea(0), |
|
52 mPageMargin(0.0) |
55 mPageMargin(0.0) |
53 { |
56 { |
54 setFlag(QGraphicsItem::ItemHasNoContents); |
57 |
55 setSizePolicy(QSizePolicy(QSizePolicy::Ignored, |
|
56 QSizePolicy::Ignored)); |
|
57 |
|
58 setupTouchArea(); |
|
59 |
|
60 //Page margin |
58 //Page margin |
61 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
59 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
62 connect(HsConfiguration::instance(), SIGNAL(propertyChanged(QString)), SLOT(onPageMarginChanged(QString))); |
60 connect(HsConfiguration::instance(), SIGNAL(propertyChanged(QString)), SLOT(onPageMarginChanged(QString))); |
63 } |
61 } |
64 |
62 |
65 /*! |
63 /*! |
66 Destructor. |
64 Destructor. |
67 */ |
65 */ |
68 HsPage::~HsPage() |
66 HsPage::~HsPage() |
69 { |
67 { |
|
68 // visuals are owned by widget host, detach those from page visual |
|
69 HsWidgetHostVisual *visual(0); |
|
70 foreach (HsWidgetHost *widget, mWidgets) { |
|
71 visual = widget->visual(); |
|
72 visual->setParent(0); |
|
73 if (visual->scene()) { |
|
74 visual->scene()->removeItem(visual); |
|
75 } |
|
76 } |
|
77 |
|
78 foreach (HsWidgetHost *widget, mNewWidgets) { |
|
79 visual = widget->visual(); |
|
80 visual->setParent(0); |
|
81 if (visual->scene()) { |
|
82 visual->scene()->removeItem(visual); |
|
83 } |
|
84 } |
|
85 |
|
86 foreach (HsWidgetHost *widget, mUnavailableWidgets) { |
|
87 visual = widget->visual(); |
|
88 visual->setParent(0); |
|
89 if (visual->scene()) { |
|
90 visual->scene()->removeItem(visual); |
|
91 } |
|
92 } |
|
93 qDeleteAll(mWidgets); |
|
94 qDeleteAll(mNewWidgets); |
|
95 qDeleteAll(mUnavailableWidgets); |
|
96 |
|
97 delete mPageVisual; |
70 delete mWallpaper; |
98 delete mWallpaper; |
71 } |
99 } |
72 |
100 |
73 /*! |
101 /*! |
74 Returns the database id. |
102 Returns the database id. |
115 mWallpaper = new HsPageWallpaper(this); |
143 mWallpaper = new HsPageWallpaper(this); |
116 } |
144 } |
117 |
145 |
118 foreach (HsWidgetData data, datas) { |
146 foreach (HsWidgetData data, datas) { |
119 HsWidgetHost *widget = new HsWidgetHost(data.id); |
147 HsWidgetHost *widget = new HsWidgetHost(data.id); |
120 mWidgets.append(widget); |
148 if (!widget->loadPresentation(Qt::Horizontal) && |
121 connectWidget(widget); |
149 !widget->loadPresentation(Qt::Vertical)) { |
122 widget->setPage(this); |
150 widget->setPage(this); |
123 widget->setParentItem(this); |
151 widget->visual()->hide(); |
124 widget->startWidget(isDefaultPage()); |
152 connectWidget(widget); |
125 } |
153 mNewWidgets << widget; |
126 |
154 } |
127 connect(HsScene::mainWindow(), |
155 else { |
|
156 mWidgets.append(widget); |
|
157 connectWidget(widget); |
|
158 widget->setPage(this); |
|
159 widget->visual()->setParentItem(this->visual()); |
|
160 widget->startWidget(isDefaultPage()); |
|
161 } |
|
162 } |
|
163 |
|
164 connect(HsGui::instance(), |
128 SIGNAL(orientationChanged(Qt::Orientation)), |
165 SIGNAL(orientationChanged(Qt::Orientation)), |
129 SLOT(onOrientationChanged(Qt::Orientation))); |
166 SLOT(onOrientationChanged(Qt::Orientation))); |
130 |
167 |
131 return true; |
168 return true; |
132 } |
169 } |
230 { |
257 { |
231 if (mNewWidgets.isEmpty()) { |
258 if (mNewWidgets.isEmpty()) { |
232 return; |
259 return; |
233 } |
260 } |
234 |
261 |
235 HsPageNewWidgetLayout *newWidgetLayout = static_cast<HsPageNewWidgetLayout *>(layout()); |
262 HsPageNewWidgetLayout *newWidgetLayout = static_cast<HsPageNewWidgetLayout *>(visual()->layout()); |
236 if (!newWidgetLayout) { |
263 if (!newWidgetLayout) { |
237 newWidgetLayout = new HsPageNewWidgetLayout(mTouchPoint); |
264 newWidgetLayout = new HsPageNewWidgetLayout(mTouchPoint); |
238 setLayout(newWidgetLayout); |
265 visual()->setLayout(newWidgetLayout); |
239 } |
266 } |
240 updateZValues(); |
267 updateZValues(); |
241 HsWidgetHost *widget = 0; |
268 HsWidgetHost *widget = 0; |
242 for (int i = 0; i < mNewWidgets.count(); ++i) { |
269 for (int i = 0; i < mNewWidgets.count(); ++i) { |
243 widget = mNewWidgets.at(i); |
270 widget = mNewWidgets.at(i); |
244 newWidgetLayout->addItem(widget); |
271 newWidgetLayout->addItem(widget); |
245 widget->setPage(this); |
272 widget->setPage(this); |
246 widget->setParentItem(this); |
273 widget->visual()->setParentItem(visual()); |
247 widget->showWidget(); |
274 widget->showWidget(); |
248 widget->show(); |
275 widget->visual()->show(); |
249 } |
276 } |
250 mWidgets << mNewWidgets; |
277 mWidgets << mNewWidgets; |
251 mNewWidgets.clear(); |
278 mNewWidgets.clear(); |
252 } |
279 } |
253 |
280 |
255 Clears new widgets list and resets layout. |
282 Clears new widgets list and resets layout. |
256 */ |
283 */ |
257 void HsPage::resetNewWidgets() |
284 void HsPage::resetNewWidgets() |
258 { |
285 { |
259 mNewWidgets.clear(); |
286 mNewWidgets.clear(); |
260 setLayout(0); |
287 visual()->setLayout(0); |
261 } |
288 } |
262 |
289 |
263 /*! |
290 /*! |
264 Remove page and all it's contained widgets from database |
291 Remove page and all it's contained widgets from database |
265 */ |
292 */ |
266 bool HsPage::deleteFromDatabase() |
293 bool HsPage::deleteFromDatabase() |
267 { |
294 { |
|
295 |
|
296 HsWidgetHostVisual *visual(0); |
268 foreach (HsWidgetHost *widget, mWidgets) { |
297 foreach (HsWidgetHost *widget, mWidgets) { |
|
298 visual = widget->visual(); |
|
299 visual->setParent(0); |
|
300 if (visual->scene()) { |
|
301 visual->scene()->removeItem(visual); |
|
302 } |
269 widget->remove(); |
303 widget->remove(); |
270 } |
304 } |
271 mWidgets.clear(); |
305 mWidgets.clear(); |
|
306 |
272 |
307 |
273 foreach (HsWidgetHost *widget, mNewWidgets) { |
308 foreach (HsWidgetHost *widget, mNewWidgets) { |
|
309 visual = widget->visual(); |
|
310 visual->setParent(0); |
|
311 if (visual->scene()) { |
|
312 visual->scene()->removeItem(visual); |
|
313 } |
274 widget->remove(); |
314 widget->remove(); |
275 } |
315 } |
276 mNewWidgets.clear(); |
316 mNewWidgets.clear(); |
277 |
317 |
278 foreach (HsWidgetHost *widget, mUnavailableWidgets) { |
318 foreach (HsWidgetHost *widget, mUnavailableWidgets) { |
|
319 visual = widget->visual(); |
|
320 visual->setParent(0); |
|
321 if (visual->scene()) { |
|
322 visual->scene()->removeItem(visual); |
|
323 } |
279 widget->remove(); |
324 widget->remove(); |
280 } |
325 } |
281 mUnavailableWidgets.clear(); |
326 mUnavailableWidgets.clear(); |
282 |
327 |
283 if (mWallpaper) { |
328 if (mWallpaper) { |
484 return HsScene::instance()->pages().indexOf(this); |
533 return HsScene::instance()->pages().indexOf(this); |
485 } |
534 } |
486 /*! |
535 /*! |
487 Create touch area for page. |
536 Create touch area for page. |
488 */ |
537 */ |
489 void HsPage::setupTouchArea() |
538 /*void HsPage::setupTouchArea() |
490 { |
539 { |
491 mTouchArea = new HsPageTouchArea(this); |
540 mTouchArea = new HsPageTouchArea(this); |
492 mTouchArea->setZValue(-1); |
541 mTouchArea->setZValue(-1); |
493 } |
542 }*/ |
494 /*! |
543 /*! |
495 Utility to connect widget signals to page. |
544 Utility to connect widget signals to page. |
496 */ |
545 */ |
497 void HsPage::connectWidget(HsWidgetHost *widget) |
546 void HsPage::connectWidget(HsWidgetHost *widget) |
498 { |
547 { |
499 connect(widget, SIGNAL(finished()), SLOT(onWidgetFinished())); |
548 connect(widget, SIGNAL(finished()), SLOT(onWidgetFinished())); |
500 connect(widget, SIGNAL(faulted()), SLOT(onWidgetFaulted())); |
549 connect(widget, SIGNAL(faulted()), SLOT(onWidgetFaulted())); |
501 connect(widget, SIGNAL(resized()), SLOT(onWidgetResized())); |
550 connect(widget->visual(), SIGNAL(resized()), SLOT(onWidgetResized())); |
502 connect(widget, SIGNAL(available()), SLOT(onWidgetAvailable())); |
551 connect(widget, SIGNAL(available()), SLOT(onWidgetAvailable())); |
503 connect(widget, SIGNAL(unavailable()), SLOT(onWidgetUnavailable())); |
552 connect(widget, SIGNAL(unavailable()), SLOT(onWidgetUnavailable())); |
504 } |
553 } |
505 /*! |
554 /*! |
506 Disconnect widget signals from page |
555 Disconnect widget signals from page |
507 */ |
556 */ |
508 void HsPage::disconnectWidget(HsWidgetHost *widget) |
557 void HsPage::disconnectWidget(HsWidgetHost *widget) |
509 { |
558 { |
|
559 widget->visual()->disconnect(this); |
510 widget->disconnect(this); |
560 widget->disconnect(this); |
511 } |
561 } |
512 /*! |
562 /*! |
513 Disconnect and remove widget |
563 Disconnect and remove widget |
514 */ |
564 */ |
537 Calculates new widget position on page when widget size changes. If page has layout then there are new widgets |
595 Calculates new widget position on page when widget size changes. If page has layout then there are new widgets |
538 and we use layout to calculate new widget positions. |
596 and we use layout to calculate new widget positions. |
539 */ |
597 */ |
540 void HsPage::onWidgetResized() |
598 void HsPage::onWidgetResized() |
541 { |
599 { |
542 if ( !layout() ) { |
600 if (!visual()->layout()) { |
543 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
601 HsWidgetHostVisual *widgetVisual = qobject_cast<HsWidgetHostVisual *>(sender()); |
544 widget->setPos(adjustedWidgetPosition(widget->geometry())); |
602 widgetVisual->setPos(adjustedWidgetPosition(widgetVisual->geometry())); |
545 } else { |
603 } else { |
546 layout()->invalidate(); |
604 visual()->layout()->invalidate(); |
547 } |
605 } |
548 } |
606 } |
549 /*! |
607 /*! |
550 Show widget if it came available |
608 Show widget if it came available |
551 */ |
609 */ |
552 void HsPage::onWidgetAvailable() |
610 void HsPage::onWidgetAvailable() |
553 { |
611 { |
554 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
612 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
613 HsWidgetHostVisual *widgetVisual(widget->visual()); |
555 |
614 |
556 mUnavailableWidgets.removeOne(widget); |
615 mUnavailableWidgets.removeOne(widget); |
557 mWidgets.append(widget); |
616 mWidgets.append(widget); |
558 |
617 |
559 widget->setParentItem(this); |
618 widgetVisual->setParentItem(visual()); |
560 widget->startWidget(isActivePage()); |
619 widget->startWidget(isActivePage()); |
561 widget->show(); |
620 widgetVisual->show(); |
562 } |
621 } |
563 /*! |
622 /*! |
564 Update internal bookkeeping and hide widget |
623 Update internal bookkeeping and hide widget |
565 */ |
624 */ |
566 void HsPage::onWidgetUnavailable() |
625 void HsPage::onWidgetUnavailable() |
567 { |
626 { |
568 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
627 HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender()); |
|
628 HsWidgetHostVisual *widgetVisual(widget->visual()); |
569 |
629 |
570 if (mWidgets.contains(widget)) { |
630 if (mWidgets.contains(widget)) { |
571 mWidgets.removeOne(widget); |
631 mWidgets.removeOne(widget); |
572 } else if (mNewWidgets.contains(widget)) { |
632 } else if (mNewWidgets.contains(widget)) { |
573 mNewWidgets.removeOne(widget); |
633 mNewWidgets.removeOne(widget); |
594 QRectF from = contentGeometry(orientationFrom); |
654 QRectF from = contentGeometry(orientationFrom); |
595 QRectF to = contentGeometry(orientation); |
655 QRectF to = contentGeometry(orientation); |
596 |
656 |
597 HsWidgetPresentationData presentation; |
657 HsWidgetPresentationData presentation; |
598 presentation.orientation = orientation; |
658 presentation.orientation = orientation; |
599 |
659 |
|
660 HsWidgetHostVisual *visual(0); |
|
661 #ifdef HSWIDGETORGANIZER_ALGORITHM |
|
662 QList<HsWidgetHost*> newWidgets; |
|
663 #endif //HSWIDGETORGANIZER_ALGORITHM |
600 foreach (HsWidgetHost *widget, mWidgets) { |
664 foreach (HsWidgetHost *widget, mWidgets) { |
|
665 visual = widget->visual(); |
601 if (!widget->getPresentation(presentation)) { |
666 if (!widget->getPresentation(presentation)) { |
|
667 #ifndef HSWIDGETORGANIZER_ALGORITHM |
602 QList<QRectF> geometries = converter->convert( |
668 QList<QRectF> geometries = converter->convert( |
603 from, QList<QRectF>() << widget->geometry(), to); |
669 from, QList<QRectF>() << visual->geometry(), to); |
604 widget->setGeometry(geometries.first()); |
670 visual->setGeometry(geometries.first()); |
605 widget->savePresentation(); |
671 widget->savePresentation(); |
|
672 #else //HSWIDGETORGANIZER_ALGORITHM |
|
673 newWidgets << widget; |
|
674 #endif //HSWIDGETORGANIZER_ALGORITHM |
606 } else { |
675 } else { |
607 QRectF adjustWidgetPosition; |
676 QRectF adjustWidgetPosition; |
608 adjustWidgetPosition = widget->geometry(); |
677 adjustWidgetPosition = visual->geometry(); |
609 adjustWidgetPosition.moveTopLeft(presentation.pos()); |
678 adjustWidgetPosition.moveTopLeft(presentation.pos()); |
610 widget->setPos(adjustedWidgetPosition(adjustWidgetPosition)); |
679 visual->setPos(adjustedWidgetPosition(adjustWidgetPosition)); |
611 widget->setZValue(presentation.zValue); |
680 visual->setZValue(presentation.zValue); |
612 widget->savePresentation(); //Needed to follow pageMargin dynamic change |
681 widget->savePresentation(); //Needed to follow pageMargin dynamic change |
613 } |
682 } |
614 } |
683 } |
|
684 |
|
685 #ifdef HSWIDGETORGANIZER_ALGORITHM |
|
686 // sort new widgets in order |
|
687 if (newWidgets.count()) { |
|
688 // TODO: read from configuration? or just use height for portrait and width for landscape (currently only height is used) |
|
689 sortOrder order(height); |
|
690 if(orientation == Qt::Horizontal) { |
|
691 order = width; |
|
692 } |
|
693 sortWidgets(order, newWidgets); |
|
694 // get rects for new widgets |
|
695 QList<QRectF> newRects; |
|
696 foreach (HsWidgetHost *newWidget, newWidgets) { |
|
697 newRects << QRectF(QPointF(), newWidget->visual()->preferredSize()); |
|
698 } |
|
699 |
|
700 // get page rect |
|
701 QRectF pageRect = contentGeometry(); |
|
702 |
|
703 // scan existing widgets rects |
|
704 QList<QRectF> existingRects; |
|
705 foreach (HsWidgetHost *widget, mWidgets) { |
|
706 if (!newWidgets.contains(widget)) { |
|
707 existingRects << QRectF(widget->visual()->pos(), widget->visual()->preferredSize()); |
|
708 } |
|
709 } |
|
710 |
|
711 // calculate new widget positions with "stuck 'em all"-algorithm |
|
712 HsWidgetPositioningOnWidgetAdd *algorithm = |
|
713 HsWidgetPositioningOnWidgetAdd::instance(); |
|
714 QList<QRectF> calculatedRects = |
|
715 algorithm->convert(pageRect, existingRects, newRects, QPointF()); |
|
716 |
|
717 for ( int i=0; i<newWidgets.count(); i++) { |
|
718 int j = mWidgets.indexOf(newWidgets.at(i)); |
|
719 mWidgets.at(j)->visual()->setGeometry(calculatedRects.at(i)); |
|
720 mWidgets.at(j)->savePresentation(); |
|
721 } |
|
722 } |
|
723 #endif //HSWIDGETORGANIZER_ALGORITHM |
|
724 |
615 } |
725 } |
616 |
726 |
617 void HsPage::onPageMarginChanged(const QString &value) |
727 void HsPage::onPageMarginChanged(const QString &value) |
618 { |
728 { |
619 if (value == "pageMargin") { |
729 if (value == "pageMargin") { |
620 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
730 mPageMargin = HSCONFIGURATION_GET(pageMargin); |
621 |
731 HsWidgetHostVisual *visual(0); |
622 if (!mWidgets.isEmpty()) { |
732 if (!mWidgets.isEmpty()) { |
623 foreach (HsWidgetHost *widget, mWidgets) { |
733 foreach (HsWidgetHost *widget, mWidgets) { |
624 widget->setPos(adjustedWidgetPosition(widget->geometry())); |
734 visual = widget->visual(); |
|
735 visual->setPos(adjustedWidgetPosition(visual->geometry())); |
625 widget->savePresentation(); |
736 widget->savePresentation(); |
626 } |
737 } |
627 } |
738 } |
628 |
739 |
629 if (!mNewWidgets.isEmpty()) { |
740 if (!mNewWidgets.isEmpty()) { |
630 foreach (HsWidgetHost *widget, mNewWidgets) { |
741 foreach (HsWidgetHost *widget, mNewWidgets) { |
631 widget->setPos(adjustedWidgetPosition(widget->geometry())); |
742 visual = widget->visual(); |
|
743 visual->setPos(adjustedWidgetPosition(visual->geometry())); |
632 widget->savePresentation(); |
744 widget->savePresentation(); |
633 } |
745 } |
634 } |
746 } |
635 } |
747 } |
636 } |
748 } |
|
749 #ifdef HSWIDGETORGANIZER_ALGORITHM |
|
750 // TODO: sorting should be done in algorithm class, make widget<->rect mapping here and move sortWidgets function to algorithm side |
|
751 /*! |
|
752 Sorts widgets in height/width order |
|
753 */ |
|
754 void HsPage::sortWidgets(sortOrder order, QList<HsWidgetHost*> &widgets) |
|
755 { |
|
756 QList<HsWidgetHost*> tmpWidgets; |
|
757 |
|
758 for ( int i = 0; i < widgets.count(); i++) { |
|
759 int index = 0; |
|
760 // add first widget to sorted list |
|
761 if (i == 0) { |
|
762 tmpWidgets << widgets.at(i); |
|
763 } else { |
|
764 // go through existing widgets in the sorted list |
|
765 for ( int j = 0; j < tmpWidgets.count(); j++) { |
|
766 // sort widgets in height order |
|
767 if (order == height) { |
|
768 /* if widgets heigth is smaller on already |
|
769 existing ones in the list -> increment index |
|
770 */ |
|
771 if (widgets.at(i)->visual()->preferredHeight() <= tmpWidgets.at(j)->visual()->preferredHeight()) { |
|
772 index++; |
|
773 } |
|
774 // sort widgets in width order |
|
775 } else { |
|
776 /* if widgets width is smaller on already |
|
777 existing ones in the sorted list -> increment index |
|
778 */ |
|
779 if (widgets.at(i)->visual()->preferredWidth() <= tmpWidgets.at(j)->visual()->preferredWidth()) { |
|
780 index++; |
|
781 } |
|
782 } |
|
783 } |
|
784 // add widget to its correct index in sorted list |
|
785 tmpWidgets.insert(index, widgets.at(i)); |
|
786 } |
|
787 } |
|
788 widgets = tmpWidgets; |
|
789 } |
|
790 #endif //HSWIDGETORGANIZER_ALGORITHM |