homescreenapp/hsdomainmodel/src/hspage.cpp
changeset 77 4b195f3bea29
parent 61 2b1b11a301d2
child 85 35368b604b28
equal deleted inserted replaced
61:2b1b11a301d2 77:4b195f3bea29
    17 
    17 
    18 #include <HbInstance>
    18 #include <HbInstance>
    19 
    19 
    20 #include "hsdomainmodeldatastructures.h"
    20 #include "hsdomainmodeldatastructures.h"
    21 #include "hspage.h"
    21 #include "hspage.h"
       
    22 #include "hspagevisual.h"
    22 #include "hspagetoucharea.h"
    23 #include "hspagetoucharea.h"
    23 #include "hspagenewwidgetlayout.h"
    24 #include "hspagenewwidgetlayout.h"
    24 #include "hsscene.h"
    25 #include "hsscene.h"
    25 #include "hsdatabase.h"
    26 #include "hsdatabase.h"
    26 #include "hswidgethost.h"
    27 #include "hswidgethost.h"
       
    28 #include "hswidgethostvisual.h"
    27 #include "hswallpaper.h"
    29 #include "hswallpaper.h"
    28 #include "hswidgetpositioningonwidgetadd.h"
    30 #include "hswidgetpositioningonwidgetadd.h"
    29 #include "hswidgetpositioningonorientationchange.h"
    31 #include "hswidgetpositioningonorientationchange.h"
    30 #include "hsconfiguration.h"
    32 #include "hsconfiguration.h"
       
    33 #include "hsgui.h"
    31 
    34 
    32 
    35 
    33 /*!
    36 /*!
    34     \class HsPage
    37     \class HsPage
    35     \ingroup group_hsdomainmodel
    38     \ingroup group_hsdomainmodel
    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)
    55       mPageMargin(0.0)
    52 {
    56 {
    53     setFlag(QGraphicsItem::ItemHasNoContents);
    57  
    54     setSizePolicy(QSizePolicy(QSizePolicy::Ignored,
    58     //Page margin
    55                               QSizePolicy::Ignored));
    59     mPageMargin = HSCONFIGURATION_GET(pageMargin);
    56 
    60     connect(HsConfiguration::instance(), SIGNAL(propertyChanged(QString)), SLOT(onPageMarginChanged(QString)));
    57     setupTouchArea();
       
    58 }
    61 }
    59 
    62 
    60 /*!
    63 /*!
    61     Destructor.
    64     Destructor.
    62 */
    65 */
    63 HsPage::~HsPage()
    66 HsPage::~HsPage()
    64 {
    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;
    65     delete mWallpaper;
    98     delete mWallpaper;
    66 }
    99 }
    67 
   100 
    68 /*!
   101 /*!
    69     Returns the database id.
   102     Returns the database id.
    78 */
   111 */
    79 void HsPage::setDatabaseId(int id)
   112 void HsPage::setDatabaseId(int id)
    80 {
   113 {
    81     mDatabaseId = id;
   114     mDatabaseId = id;
    82 }
   115 }
    83 
   116 /*
    84 void HsPage::setGeometry(const QRectF &rect)
   117 void HsPage::setGeometry(const QRectF &rect)
    85 {
   118 {
    86     if (mTouchArea) {
   119     if (mTouchArea) {
    87         mTouchArea->resize(rect.size());
   120         mTouchArea->resize(rect.size());
    88     }
   121     }
    89 
   122 
    90     HbWidget::setGeometry(rect);
   123     HbWidget::setGeometry(rect);
    91 }
   124 }
    92 
   125 */
    93 /*!
   126 /*!
    94     Loads widgets.
   127     Loads widgets.
    95 */
   128 */
    96 bool HsPage::load()
   129 bool HsPage::load()
    97 {
   130 {
   110         mWallpaper = new HsPageWallpaper(this);
   143         mWallpaper = new HsPageWallpaper(this);
   111     }
   144     }
   112 
   145 
   113     foreach (HsWidgetData data, datas) {
   146     foreach (HsWidgetData data, datas) {
   114         HsWidgetHost *widget = new HsWidgetHost(data.id);
   147         HsWidgetHost *widget = new HsWidgetHost(data.id);
   115         mWidgets.append(widget);
   148         if (!widget->loadPresentation(Qt::Horizontal) &&
   116         connectWidget(widget);
   149             !widget->loadPresentation(Qt::Vertical)) {
   117         widget->setPage(this);
   150             widget->setPage(this);
   118         widget->setParentItem(this);
   151             widget->visual()->hide();
   119         widget->startWidget(isDefaultPage());
   152             connectWidget(widget);
   120     }
   153             mNewWidgets << widget;            
   121 
   154         }
   122     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(),
   123         SIGNAL(orientationChanged(Qt::Orientation)),
   165         SIGNAL(orientationChanged(Qt::Orientation)),
   124         SLOT(onOrientationChanged(Qt::Orientation)));
   166         SLOT(onOrientationChanged(Qt::Orientation)));
   125 
   167 
   126     return true;
   168     return true;
   127 }
   169 }
   128 
   170 
   129 /*!
   171 /*!
   130     Return wallpaper. 
   172     Return wallpaper.
   131 */
   173 */
   132 HsWallpaper *HsPage::wallpaper() const
   174 HsWallpaper *HsPage::wallpaper() const
   133 {
   175 {
   134     return mWallpaper;
   176     return mWallpaper;
   135 }
   177 }
   150         return false;
   192         return false;
   151     }
   193     }
   152 
   194 
   153     connectWidget(widgetHost);
   195     connectWidget(widgetHost);
   154     mWidgets << widgetHost;
   196     mWidgets << widgetHost;
   155     widgetHost->setParentItem(this);
   197     widgetHost->visual()->setParentItem(visual());
   156 
   198 
   157     return true;
   199     return true;
   158  }
   200  }
       
   201 
   159 /*!
   202 /*!
   160     Remove given \a widgetHost from a page. Widget is not deleted. 
   203     Remove given \a widgetHost from a page. Widget is not deleted. 
   161     Returns true if successful
   204     Returns true if successful
   162 */
   205 */
   163 bool HsPage::removeWidget(HsWidgetHost *widgetHost)
   206 bool HsPage::removeWidget(HsWidgetHost *widgetHost)
   166         return false;
   209         return false;
   167     }
   210     }
   168 
   211 
   169     disconnectWidget(widgetHost);
   212     disconnectWidget(widgetHost);
   170     mWidgets.removeOne(widgetHost);
   213     mWidgets.removeOne(widgetHost);
   171     widgetHost->setParentItem(0);
   214     widgetHost->visual()->setParentItem(0);
   172 
   215 
   173     return true;
   216     return true;
   174 }
   217 }
       
   218 
   175 /*!
   219 /*!
   176     Returns list of new widgets belonging to a page. Widgets which are
   220     Returns list of new widgets belonging to a page. Widgets which are
   177     not yet layouted are considered as new widgets. 
   221     not yet layouted are considered as new widgets. 
   178 */
   222 */
   179 QList<HsWidgetHost *> HsPage::newWidgets()
   223 QList<HsWidgetHost *> HsPage::newWidgets()
   193     }
   237     }
   194 
   238 
   195     if (mNewWidgets.contains(widgetHost)) {
   239     if (mNewWidgets.contains(widgetHost)) {
   196         return true;
   240         return true;
   197     }
   241     }
   198 
   242     
   199     HsWidgetPresentationData presentation;
   243     widgetHost->setPage(this);    
   200     presentation.orientation = HsScene::orientation();
   244 
   201     if (!widgetHost->getPresentation(presentation)) {
   245     widgetHost->visual()->hide();
   202         presentation.orientation = HsScene::orientation();
       
   203         presentation.setPos(mTouchPoint);
       
   204         presentation.zValue = 0;
       
   205         widgetHost->savePresentation(presentation);
       
   206     }
       
   207 
       
   208     widgetHost->hide();
       
   209     widgetHost->setPos(presentation.x, presentation.y);
       
   210     widgetHost->setZValue(presentation.zValue);
       
   211 
   246 
   212     connectWidget(widgetHost);
   247     connectWidget(widgetHost);
   213     mNewWidgets << widgetHost;
   248     mNewWidgets << widgetHost;
   214 
   249 
   215     return true;
   250     return true;
   222 {
   257 {
   223     if (mNewWidgets.isEmpty()) {
   258     if (mNewWidgets.isEmpty()) {
   224         return;
   259         return;
   225     }
   260     }
   226 
   261 
   227     HsPageNewWidgetLayout *newWidgetLayout = static_cast<HsPageNewWidgetLayout *>(layout());
   262     HsPageNewWidgetLayout *newWidgetLayout = static_cast<HsPageNewWidgetLayout *>(visual()->layout());
   228     if (!newWidgetLayout) {
   263     if (!newWidgetLayout) {
   229         newWidgetLayout = new HsPageNewWidgetLayout(mTouchPoint);
   264         newWidgetLayout = new HsPageNewWidgetLayout(mTouchPoint);
   230         setLayout(newWidgetLayout);
   265         visual()->setLayout(newWidgetLayout);
   231     }    
   266     }    
   232     updateZValues();
   267     updateZValues();
   233     HsWidgetHost *widget = 0;
   268     HsWidgetHost *widget = 0;
   234     for (int i = 0; i < mNewWidgets.count(); ++i) {
   269     for (int i = 0; i < mNewWidgets.count(); ++i) {
   235         widget = mNewWidgets.at(i);
   270         widget = mNewWidgets.at(i);
   236         newWidgetLayout->addItem(widget);
   271         newWidgetLayout->addItem(widget);
   237         widget->setPage(this);
   272         widget->setPage(this);
   238         widget->setParentItem(this);
   273         widget->visual()->setParentItem(visual());
   239         widget->showWidget();
   274         widget->showWidget();
   240         widget->show();
   275         widget->visual()->show();
   241     }
   276     }
   242     mWidgets << mNewWidgets;
   277     mWidgets << mNewWidgets;
   243     mNewWidgets.clear();
   278     mNewWidgets.clear();
   244 }
   279 }
   245 
   280 
   246 /*!
   281 /*!
       
   282     Clears new widgets list and resets layout.
       
   283 */
       
   284 void HsPage::resetNewWidgets()
       
   285 {
       
   286     mNewWidgets.clear();
       
   287     visual()->setLayout(0);
       
   288 }
       
   289 
       
   290 /*!
   247     Remove page and all it's contained widgets from database 
   291     Remove page and all it's contained widgets from database 
   248 */
   292 */
   249 bool HsPage::deleteFromDatabase()
   293 bool HsPage::deleteFromDatabase()
   250 {
   294 {
       
   295     
       
   296     HsWidgetHostVisual *visual(0);
   251     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         }
   252         widget->remove();
   303         widget->remove();
   253     }
   304     }
   254     mWidgets.clear();
   305     mWidgets.clear();
       
   306     
   255 
   307 
   256     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         }
   257         widget->remove();
   314         widget->remove();
   258     }
   315     }
   259     mNewWidgets.clear();
   316     mNewWidgets.clear();
   260 
   317 
   261     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         }
   262         widget->remove();
   324         widget->remove();
   263     }
   325     }
   264     mUnavailableWidgets.clear();
   326     mUnavailableWidgets.clear();
   265 
   327     
       
   328     if (mWallpaper) {
       
   329         mWallpaper->remove();
       
   330     }
   266     return HsDatabase::instance()->deletePage(mDatabaseId);
   331     return HsDatabase::instance()->deletePage(mDatabaseId);
   267 }
   332 }
       
   333 
   268 /*!
   334 /*!
   269     Return list of widgets belonging to a page 
   335     Return list of widgets belonging to a page 
   270 */
   336 */
   271 QList<HsWidgetHost *> HsPage::widgets() const
   337 QList<HsWidgetHost *> HsPage::widgets() const
   272 {
   338 {
   287 */
   353 */
   288 void HsPage::setRemovable(bool removable)
   354 void HsPage::setRemovable(bool removable)
   289 {
   355 {
   290     mRemovable = removable;
   356     mRemovable = removable;
   291 }
   357 }
       
   358 
   292 /*!
   359 /*!
   293     Return true if page is default page.
   360     Return true if page is default page.
   294 */
   361 */
   295 bool HsPage::isDefaultPage() const
   362 bool HsPage::isDefaultPage() const
   296 {
   363 {
   297     return mDatabaseId == HSCONFIGURATION_GET(defaultPageId);
   364     return mDatabaseId == HSCONFIGURATION_GET(defaultPageId);
   298 }
   365 }
       
   366 
   299 /*!
   367 /*!
   300     Return true if page is active page.
   368     Return true if page is active page.
   301 */
   369 */
   302 bool HsPage::isActivePage() const
   370 bool HsPage::isActivePage() const
   303 {
   371 {
   304     return this == HsScene::instance()->activePage();
   372     return this == HsScene::instance()->activePage();
   305 }
   373 }
       
   374 
   306 /*!
   375 /*!
   307     Create page into database and return instance of a new page.
   376     Create page into database and return instance of a new page.
   308 */
   377 */
   309 HsPage *HsPage::createInstance(const HsPageData &pageData)
   378 HsPage *HsPage::createInstance(const HsPageData &pageData)
   310 {
   379 {
   320 
   389 
   321     return 0;
   390     return 0;
   322 }
   391 }
   323 
   392 
   324 /*!
   393 /*!
       
   394     The widget is bounded in the rectangle which is smaller by pageMargin on all sides of page.
       
   395 */
       
   396 QPointF HsPage::adjustedWidgetPosition(const QRectF &origWidgetRect)
       
   397 {
       
   398     QRectF widgetAreaRect = contentGeometry();
       
   399     qreal widgetX = qBound(widgetAreaRect.left(), origWidgetRect.x(), widgetAreaRect.right() - origWidgetRect.width());
       
   400     qreal widgetY = qBound(widgetAreaRect.top(), origWidgetRect.y(), widgetAreaRect.bottom() - origWidgetRect.height());
       
   401 
       
   402     return QPointF(widgetX, widgetY);
       
   403 }
       
   404 
       
   405 /*!
       
   406     Returns rect of rectangular where widgets are allowed to be placed in the page.
       
   407 */
       
   408 QRectF HsPage::contentGeometry()
       
   409 {
       
   410     return contentGeometry(HsGui::instance()->orientation());
       
   411 }
       
   412 
       
   413 /*!
       
   414     Returns rect of rectangular where widgets are allowed to be placed in the page.
       
   415 */
       
   416 QRectF HsPage::contentGeometry(Qt::Orientation orientation)
       
   417 {
       
   418     QRectF pageRect = HsGui::instance()->layoutRect();
       
   419 
       
   420     if (orientation != HsGui::instance()->orientation()) {
       
   421         qreal width = pageRect.width();
       
   422         qreal height = pageRect.height();
       
   423         pageRect.setWidth(height);
       
   424         pageRect.setHeight(width);
       
   425     }
       
   426 
       
   427     //Take care of chrome in both orientation
       
   428     pageRect.setTop(64);
       
   429 
       
   430     //Shrink by page margins at each side
       
   431     return pageRect.adjusted(mPageMargin, mPageMargin, -mPageMargin, -mPageMargin);
       
   432 }
       
   433 
       
   434 /*!
       
   435     Returns rect of rectangular where widgets are allowed to be placed in the page.
       
   436 */
       
   437 QRectF HsPage::contentRect()
       
   438 {
       
   439     return contentRect(HsGui::instance()->orientation());
       
   440 }
       
   441 
       
   442 /*!
       
   443     Returns rect of rectangular where widgets are allowed to be placed in the page.
       
   444 */
       
   445 QRectF HsPage::contentRect(Qt::Orientation orientation)
       
   446 {
       
   447     QRectF rect = contentGeometry(orientation);
       
   448     rect.moveTopLeft(QPointF(0,0));
       
   449     return rect;
       
   450 }
       
   451 
       
   452 HsPageVisual *HsPage::visual() const
       
   453 {
       
   454     return mPageVisual;
       
   455 }
       
   456 /*!
   325     Calls onShow() for contained widgets.
   457     Calls onShow() for contained widgets.
   326 */
   458 */
   327 void HsPage::showWidgets()
   459 void HsPage::showWidgets()
   328 {
   460 {
   329     foreach (HsWidgetHost *widget, mWidgets) {
   461     foreach (HsWidgetHost *widget, mWidgets) {
   330         if (widget->parentItem() == this) {
   462         if (widget->visual()->parentItem() == visual()) {
   331             widget->showWidget();
   463             widget->showWidget();
   332         }
   464         }
   333     }
   465     }
   334 }
   466 }
   335 
   467 
   337     Calls onHide() for contained widgets.
   469     Calls onHide() for contained widgets.
   338 */
   470 */
   339 void HsPage::hideWidgets()
   471 void HsPage::hideWidgets()
   340 {
   472 {
   341     foreach (HsWidgetHost *widget, mWidgets) {
   473     foreach (HsWidgetHost *widget, mWidgets) {
   342         if (widget->parentItem() == this) {
   474         if (widget->visual()->parentItem() == visual()) {
   343             widget->hideWidget();
   475             widget->hideWidget();
   344         }
   476         }
   345     }
   477     }
   346 }
   478 }
   347 
   479 
   348 /*!
   480 /*!
   349     Propogate online state to widgets.
   481     Propagate online state to widgets.
   350 */
   482 */
   351 void HsPage::setOnline(bool online)
   483 void HsPage::setOnline(bool online)
   352 {
   484 {
   353     foreach (HsWidgetHost *widget, mNewWidgets) {
   485     foreach (HsWidgetHost *widget, mNewWidgets) {
   354         widget->setOnline(online);
   486         widget->setOnline(online);
   355     }
   487     }
   356     foreach (HsWidgetHost *widget, mWidgets) {
   488     foreach (HsWidgetHost *widget, mWidgets) {
   357         widget->setOnline(online);
   489         widget->setOnline(online);
   358     }
   490     }
   359 }
   491 }
       
   492 
   360 /*!
   493 /*!
   361     Update widgets z-values and persist those. Active widget has top most 
   494     Update widgets z-values and persist those. Active widget has top most 
   362     z-value.
   495     z-value.
   363 */
   496 */
   364 void HsPage::updateZValues()
   497 void HsPage::updateZValues()
   366     int z = 0;
   499     int z = 0;
   367 
   500 
   368     if (!mWidgets.isEmpty()) {
   501     if (!mWidgets.isEmpty()) {
   369         QMultiMap<qreal, HsWidgetHost *> map;
   502         QMultiMap<qreal, HsWidgetHost *> map;
   370         foreach (HsWidgetHost *widget, mWidgets) {
   503         foreach (HsWidgetHost *widget, mWidgets) {
   371             map.insert(widget->zValue(), widget);
   504             map.insert(widget->visual()->zValue(), widget);
   372         }
   505         }
   373 
   506 
   374         QList<HsWidgetHost *> sortedWidgets = map.values();
   507         QList<HsWidgetHost *> sortedWidgets = map.values();
   375 
   508 
   376         HsWidgetHost *activeWidget = HsScene::instance()->activeWidget();
   509         HsWidgetHost *activeWidget = HsScene::instance()->activeWidget();
   378             sortedWidgets.removeOne(activeWidget);
   511             sortedWidgets.removeOne(activeWidget);
   379             sortedWidgets.append(activeWidget);
   512             sortedWidgets.append(activeWidget);
   380         }
   513         }
   381 
   514 
   382         foreach (HsWidgetHost *widget, sortedWidgets) {
   515         foreach (HsWidgetHost *widget, sortedWidgets) {
   383             widget->setZValue(z++);
   516             widget->visual()->setZValue(z++);
   384             widget->savePresentation();
   517             widget->savePresentation();
   385         }
   518         }
   386     }
   519     }
   387 
   520 
   388     if (!mNewWidgets.isEmpty()) {
   521     if (!mNewWidgets.isEmpty()) {
   389         foreach (HsWidgetHost *widget, mNewWidgets) {
   522         foreach (HsWidgetHost *widget, mNewWidgets) {
   390             widget->setZValue(z++);
   523             widget->visual()->setZValue(z++);
   391             widget->savePresentation();
   524             widget->savePresentation();
   392         }
   525         }
   393     }
   526     }
   394 }
   527 }
   395 /*!
   528 /*!
   400     return HsScene::instance()->pages().indexOf(this);
   533     return HsScene::instance()->pages().indexOf(this);
   401 }
   534 }
   402 /*!
   535 /*!
   403     Create touch area for page.
   536     Create touch area for page.
   404 */
   537 */
   405 void HsPage::setupTouchArea()
   538 /*void HsPage::setupTouchArea()
   406 {
   539 {
   407     mTouchArea = new HsPageTouchArea(this);
   540     mTouchArea = new HsPageTouchArea(this);
   408     mTouchArea->setZValue(-1);
   541     mTouchArea->setZValue(-1);
   409 }
   542 }*/
   410 /*!
   543 /*!
   411     Utility to connect widget signals to page.
   544     Utility to connect widget signals to page.
   412 */
   545 */
   413 void HsPage::connectWidget(HsWidgetHost *widget)
   546 void HsPage::connectWidget(HsWidgetHost *widget)
   414 {
   547 {
   415     connect(widget, SIGNAL(finished()), SLOT(onWidgetFinished()));
   548     connect(widget, SIGNAL(finished()), SLOT(onWidgetFinished()));
   416     connect(widget, SIGNAL(faulted()), SLOT(onWidgetFaulted()));
   549     connect(widget, SIGNAL(faulted()), SLOT(onWidgetFaulted()));
   417     connect(widget, SIGNAL(resized()), SLOT(onWidgetResized()));
   550     connect(widget->visual(), SIGNAL(resized()), SLOT(onWidgetResized()));
   418     connect(widget, SIGNAL(available()), SLOT(onWidgetAvailable()));
   551     connect(widget, SIGNAL(available()), SLOT(onWidgetAvailable()));
   419     connect(widget, SIGNAL(unavailable()), SLOT(onWidgetUnavailable()));
   552     connect(widget, SIGNAL(unavailable()), SLOT(onWidgetUnavailable()));
   420 }
   553 }
   421 /*!
   554 /*!
   422     Disconnect widget signals from page
   555     Disconnect widget signals from page
   423 */
   556 */
   424 void HsPage::disconnectWidget(HsWidgetHost *widget)
   557 void HsPage::disconnectWidget(HsWidgetHost *widget)
   425 {
   558 {
       
   559     widget->visual()->disconnect(this);
   426     widget->disconnect(this);
   560     widget->disconnect(this);
   427 }
   561 }
   428 /*!
   562 /*!
   429     Disconnect and remove widget
   563     Disconnect and remove widget
   430 */
   564 */
   435     // It can be in new widget list if we haven't layouted it yet
   569     // It can be in new widget list if we haven't layouted it yet
   436     // or layouted new widget and widget list
   570     // or layouted new widget and widget list
   437     if (!mNewWidgets.removeOne(widget)) {
   571     if (!mNewWidgets.removeOne(widget)) {
   438         mWidgets.removeOne(widget);
   572         mWidgets.removeOne(widget);
   439     }
   573     }
       
   574     if (widget){     
       
   575         HsWidgetHostVisual *visual = widget->visual();
       
   576         visual->setParentItem(0);
       
   577         if (visual->scene()) {
       
   578             visual->scene()->removeItem(visual);
       
   579         }
       
   580     }
       
   581     
   440 
   582 
   441     disconnectWidget(widget);
   583     disconnectWidget(widget);
   442     widget->remove();
   584     widget->remove();
   443 }
   585 }
   444 /*!
   586 /*!
   453     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
   454     and we use layout to calculate new widget positions.
   596     and we use layout to calculate new widget positions.
   455 */
   597 */
   456 void HsPage::onWidgetResized()
   598 void HsPage::onWidgetResized()
   457 {
   599 {
   458     if ( !layout() ) {
   600     if (!visual()->layout()) {
   459         HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender());
   601         HsWidgetHostVisual *widgetVisual = qobject_cast<HsWidgetHostVisual *>(sender());
   460         QRectF widgetRect = widget->geometry();
   602         widgetVisual->setPos(adjustedWidgetPosition(widgetVisual->geometry()));
   461         QRectF pageRect = HsScene::mainWindow()->layoutRect();
       
   462         qreal widgetX = qBound(qreal(0), widgetRect.x(), pageRect.width() - widgetRect.width());
       
   463         qreal widgetY = qBound(qreal(64), widgetRect.y(), pageRect.height() - widgetRect.height());
       
   464         widget->setPos(widgetX, widgetY);
       
   465     } else {
   603     } else {
   466         layout()->invalidate();
   604         visual()->layout()->invalidate();
   467     }
   605     }
   468 }
   606 }
   469 /*!
   607 /*!
   470     Show widget if it came available
   608     Show widget if it came available
   471 */
   609 */
   472 void HsPage::onWidgetAvailable()
   610 void HsPage::onWidgetAvailable()
   473 {
   611 {
   474     HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender());
   612     HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender());
       
   613     HsWidgetHostVisual *widgetVisual(widget->visual());
   475 
   614 
   476     mUnavailableWidgets.removeOne(widget);
   615     mUnavailableWidgets.removeOne(widget);
   477     mWidgets.append(widget);
   616     mWidgets.append(widget);
   478 
   617 
   479     widget->setParentItem(this);
   618     widgetVisual->setParentItem(visual());
   480     widget->startWidget(isActivePage());
   619     widget->startWidget(isActivePage());
   481     widget->show();
   620     widgetVisual->show();
   482 }
   621 }
   483 /*!
   622 /*!
   484     Update internal bookkeeping and hide widget
   623     Update internal bookkeeping and hide widget
   485 */
   624 */
   486 void HsPage::onWidgetUnavailable()
   625 void HsPage::onWidgetUnavailable()
   487 {
   626 {
   488     HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender());
   627     HsWidgetHost *widget = qobject_cast<HsWidgetHost *>(sender());
       
   628     HsWidgetHostVisual *widgetVisual(widget->visual());
   489 
   629 
   490     if (mWidgets.contains(widget)) {
   630     if (mWidgets.contains(widget)) {
   491         mWidgets.removeOne(widget);
   631         mWidgets.removeOne(widget);
   492     } else if (mNewWidgets.contains(widget)) {
   632     } else if (mNewWidgets.contains(widget)) {
   493         mNewWidgets.removeOne(widget);
   633         mNewWidgets.removeOne(widget);
   495         return;
   635         return;
   496     }
   636     }
   497 
   637 
   498     mUnavailableWidgets.append(widget);
   638     mUnavailableWidgets.append(widget);
   499 
   639 
   500     widget->hide();
   640     widgetVisual->hide();
   501     widget->setParentItem(0);
   641     widgetVisual->setParentItem(0);
   502 }
   642 }
       
   643 
   503 /*!
   644 /*!
   504     Run positioning algorithm for widgets which don't have position on 
   645     Run positioning algorithm for widgets which don't have position on 
   505     target orientation. Otherwise set orientation positions for widgets.
   646     target orientation. Otherwise set orientation positions for widgets.
   506 */
   647 */
   507 void HsPage::onOrientationChanged(Qt::Orientation orientation)
   648 void HsPage::onOrientationChanged(Qt::Orientation orientation)
   508 {
   649 {
   509     QRectF rect = HsScene::mainWindow()->layoutRect();
       
   510 
       
   511     HsWidgetPositioningOnOrientationChange *converter =
   650     HsWidgetPositioningOnOrientationChange *converter =
   512         HsWidgetPositioningOnOrientationChange::instance();
   651         HsWidgetPositioningOnOrientationChange::instance();
   513 
   652 
   514     qreal chrome = 64;
   653     Qt::Orientation orientationFrom = orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical;
   515     QRectF from(0, chrome, rect.height(), rect.width() - chrome);
   654     QRectF from = contentGeometry(orientationFrom);
   516     QRectF to(0, chrome, rect.width(), rect.height() - chrome);
   655     QRectF to = contentGeometry(orientation);
   517 
   656 
   518     HsWidgetPresentationData presentation;
   657     HsWidgetPresentationData presentation;
   519     presentation.orientation = orientation;
   658     presentation.orientation = orientation;
   520 
   659     
       
   660     HsWidgetHostVisual *visual(0);
       
   661 #ifdef HSWIDGETORGANIZER_ALGORITHM
       
   662     QList<HsWidgetHost*> newWidgets;
       
   663 #endif //HSWIDGETORGANIZER_ALGORITHM    
   521     foreach (HsWidgetHost *widget, mWidgets) {
   664     foreach (HsWidgetHost *widget, mWidgets) {
       
   665         visual = widget->visual();
   522         if (!widget->getPresentation(presentation)) {
   666         if (!widget->getPresentation(presentation)) {
       
   667 #ifndef HSWIDGETORGANIZER_ALGORITHM
   523             QList<QRectF> geometries = converter->convert(
   668             QList<QRectF> geometries = converter->convert(
   524                 from, QList<QRectF>() << widget->geometry(), to);
   669                 from, QList<QRectF>() << visual->geometry(), to);
   525             widget->setGeometry(geometries.first());
   670             visual->setGeometry(geometries.first());
   526             widget->savePresentation();
   671             widget->savePresentation();
       
   672 #else //HSWIDGETORGANIZER_ALGORITHM
       
   673             newWidgets << widget;
       
   674 #endif //HSWIDGETORGANIZER_ALGORITHM
   527         } else {
   675         } else {
   528             widget->setPos(presentation.pos());
   676             QRectF adjustWidgetPosition;
   529             widget->setZValue(presentation.zValue);
   677             adjustWidgetPosition = visual->geometry();
   530         }
   678             adjustWidgetPosition.moveTopLeft(presentation.pos());
   531     }
   679             visual->setPos(adjustedWidgetPosition(adjustWidgetPosition));
   532 }
   680             visual->setZValue(presentation.zValue);
   533 
   681             widget->savePresentation(); //Needed to follow pageMargin dynamic change
   534 /*!
   682         }
   535     Clears new widgets list and resets layout.
   683     }
   536 */
   684     
   537 void HsPage::resetNewWidgets()
   685 #ifdef HSWIDGETORGANIZER_ALGORITHM
   538 {
   686     // sort new widgets in order
   539     mNewWidgets.clear();
   687     if (newWidgets.count()) {
   540     setLayout(0);
   688         // TODO: read from configuration? or just use height for portrait and width for landscape (currently only height is used)
   541 }
   689         sortOrder order(height);
   542 
   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     
       
   725 }
       
   726 
       
   727 void HsPage::onPageMarginChanged(const QString &value)
       
   728 {
       
   729     if (value == "pageMargin") {
       
   730         mPageMargin = HSCONFIGURATION_GET(pageMargin);
       
   731         HsWidgetHostVisual *visual(0);
       
   732         if (!mWidgets.isEmpty()) {
       
   733             foreach (HsWidgetHost *widget, mWidgets) {
       
   734                 visual = widget->visual();
       
   735                 visual->setPos(adjustedWidgetPosition(visual->geometry()));
       
   736                 widget->savePresentation();
       
   737             }
       
   738         }
       
   739 
       
   740         if (!mNewWidgets.isEmpty()) {
       
   741             foreach (HsWidgetHost *widget, mNewWidgets) {
       
   742                 visual = widget->visual();
       
   743                 visual->setPos(adjustedWidgetPosition(visual->geometry()));
       
   744                 widget->savePresentation();
       
   745             }
       
   746         }
       
   747     }
       
   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