homescreenapp/hsdomainmodel/src/hswidgethost.cpp
changeset 62 341166945d65
parent 55 03646e8da489
child 69 87476091b3f5
equal deleted inserted replaced
57:2e2dc3d30ca8 62:341166945d65
    30 #include <qservicemanager.h>
    30 #include <qservicemanager.h>
    31 #include <qservicefilter.h>
    31 #include <qservicefilter.h>
    32 #include <qserviceinterfacedescriptor.h>
    32 #include <qserviceinterfacedescriptor.h>
    33 
    33 
    34 #include <HbInstantFeedback>
    34 #include <HbInstantFeedback>
       
    35 #include <HbTouchArea>
    35 
    36 
    36 #include "hsdatabase.h"
    37 #include "hsdatabase.h"
    37 #include "hsdomainmodeldatastructures.h"
    38 #include "hsdomainmodeldatastructures.h"
    38 #include "hsscene.h"
    39 #include "hsscene.h"
    39 #include "hspage.h"
    40 #include "hspage.h"
    40 #include "hswidgethost.h"
    41 #include "hswidgethost.h"
       
    42 #include "hswidgettoucharea.h"
    41 #include "hswidgetcomponentregistry.h"
    43 #include "hswidgetcomponentregistry.h"
    42 #include "hswidgetcomponent.h"
    44 #include "hswidgetcomponent.h"
    43 #include "hsconfiguration.h"
    45 #include "hsconfiguration.h"
       
    46 #include "hscontentservice.h"
    44 
    47 
    45 // Helper macros for connecting state entry and exit actions.
    48 // Helper macros for connecting state entry and exit actions.
    46 #define ENTRY_ACTION(state, action) \
    49 #define ENTRY_ACTION(state, action) \
    47     connect(state, SIGNAL(entered()), SLOT(action()));
    50     connect(state, SIGNAL(entered()), SLOT(action()));
    48 #define EXIT_ACTION(state, action) \
    51 #define EXIT_ACTION(state, action) \
    49     connect(state, SIGNAL(exited()), SLOT(action()));
    52     connect(state, SIGNAL(exited()), SLOT(action()));
    50 
    53 
    51 QTM_USE_NAMESPACE
    54 QTM_USE_NAMESPACE
    52 
    55 
       
    56 
       
    57 /*!
       
    58     \class HsWidgetHost
       
    59     \ingroup group_hsdomainmodel
       
    60     \brief Each widget is controlled by the home screen framework through a widget host.
       
    61 */
       
    62 
       
    63 /*!
       
    64     Constructs a new widget host with given \a databaseId and
       
    65     \a parent item.
       
    66 */
    53 HsWidgetHost::HsWidgetHost(int databaseId, QGraphicsItem *parent)
    67 HsWidgetHost::HsWidgetHost(int databaseId, QGraphicsItem *parent)
    54   : HbWidget(parent),
    68   : HbWidget(parent),
    55     mDatabaseId(databaseId),
    69     mDatabaseId(databaseId),
    56     mStateMachine(0),
    70     mStateMachine(0),
    57     mWidget(0),
    71     mWidget(0),
    66     grabGesture(Qt::TapAndHoldGesture);
    80     grabGesture(Qt::TapAndHoldGesture);
    67     grabGesture(Qt::PanGesture);
    81     grabGesture(Qt::PanGesture);
    68     grabGesture(Qt::PinchGesture);
    82     grabGesture(Qt::PinchGesture);
    69     grabGesture(Qt::SwipeGesture);
    83     grabGesture(Qt::SwipeGesture);
    70     grabGesture(Qt::CustomGesture);
    84     grabGesture(Qt::CustomGesture);
    71 
    85     
       
    86     setupTouchArea();
    72     setupEffects();
    87     setupEffects();
    73     setupStates();
    88     setupStates();
    74 }
    89 }
    75 
    90 
       
    91 /*!
       
    92     Destructor.
       
    93 */
    76 HsWidgetHost::~HsWidgetHost()
    94 HsWidgetHost::~HsWidgetHost()
    77 {
    95 {
    78 }
    96 }
    79 
    97 
       
    98 /*!
       
    99     Creates a new widget host instance based on the give
       
   100     \a widgetData and \a preferences. Returns the created
       
   101     instance. Return 0 in failure cases.
       
   102 */
    80 HsWidgetHost *HsWidgetHost::createInstance(HsWidgetData &widgetData, 
   103 HsWidgetHost *HsWidgetHost::createInstance(HsWidgetData &widgetData, 
    81                                            const QVariantHash &preferences)
   104                                            const QVariantHash &preferences)
    82 {
   105 {
    83     HsDatabase *db = HsDatabase::instance();
   106     HsDatabase *db = HsDatabase::instance();
    84 
   107 
    88     } else {
   111     } else {
    89         return 0;
   112         return 0;
    90     }
   113     }
    91 }
   114 }
    92 
   115 
       
   116 /*!
       
   117     Returns the databaseId.
       
   118 */
    93 int HsWidgetHost::databaseId() const
   119 int HsWidgetHost::databaseId() const
    94 {
   120 {
    95     return mDatabaseId;
   121     return mDatabaseId;
    96 }
   122 }
    97 
   123 
       
   124 /*!
       
   125     Sets the containing \a page for this widget host.
       
   126     Returns true on success, otherwise returns false.
       
   127 */
    98 bool HsWidgetHost::setPage(HsPage *page)
   128 bool HsWidgetHost::setPage(HsPage *page)
    99 {
   129 {
   100     HsDatabase *db = HsDatabase::instance();
   130     HsDatabase *db = HsDatabase::instance();
   101     
   131     
   102     HsWidgetData data;
   132     HsWidgetData data;
   116 
   146 
   117     mPage = page;
   147     mPage = page;
   118     return true;
   148     return true;
   119 }
   149 }
   120  
   150  
       
   151 /*!
       
   152     Returns the containing page for this widget. Returns 0 
       
   153     if this widget has no containg page.
       
   154 */
   121 HsPage *HsWidgetHost::page() const
   155 HsPage *HsWidgetHost::page() const
   122 {
   156 {
   123     return mPage;
   157     return mPage;
   124 }
   158 }
   125 
   159 
   126 bool HsWidgetHost::isPannable(QGraphicsSceneMouseEvent *event)
   160 /*!
   127 {
   161     Loads presentation based on the current orientation.
   128     bool result = false;
   162     Returns true on success, otherwise returns false.
   129     mIsPannableMethod.invoke(mWidget, Q_RETURN_ARG(bool, result), Q_ARG(QGraphicsSceneMouseEvent *,event));
   163 */
   130     return result;
       
   131 }
       
   132 
       
   133 bool HsWidgetHost::loadPresentation()
   164 bool HsWidgetHost::loadPresentation()
   134 {
   165 {
   135     return loadPresentation(HsScene::orientation());
   166     return loadPresentation(HsScene::orientation());
   136 }
   167 }
   137 
   168 
       
   169 /*!
       
   170     Loads presentation based on the given \a orientation.
       
   171     Returns true on success, otherwise returns false.
       
   172 */
   138 bool HsWidgetHost::loadPresentation(Qt::Orientation orientation)
   173 bool HsWidgetHost::loadPresentation(Qt::Orientation orientation)
   139 {
   174 {
   140     HsDatabase *db = HsDatabase::instance();
   175     HsDatabase *db = HsDatabase::instance();
   141         
   176         
   142     HsWidgetPresentationData data;
   177     HsWidgetPresentationData data;
   148     setPos(data.x, data.y);
   183     setPos(data.x, data.y);
   149     setZValue(data.zValue);
   184     setZValue(data.zValue);
   150     return true;
   185     return true;
   151 }
   186 }
   152 
   187 
       
   188 /*!
       
   189     Saves the current presentation.
       
   190     Returns true on success, otherwise returns false.
       
   191 */
   153 bool HsWidgetHost::savePresentation()
   192 bool HsWidgetHost::savePresentation()
   154 {
   193 {
   155     return savePresentation(HsScene::orientation());
   194     return savePresentation(HsScene::orientation());
   156 }
   195 }
   157 
   196 
       
   197 /*!
       
   198     Saves the current presentation for the given \a orientation.
       
   199     Returns true on success, otherwise returns false.
       
   200 */
   158 bool HsWidgetHost::savePresentation(Qt::Orientation orientation)
   201 bool HsWidgetHost::savePresentation(Qt::Orientation orientation)
   159 {
   202 {
   160     HsDatabase *db = HsDatabase::instance();
   203     HsDatabase *db = HsDatabase::instance();
   161         
   204         
   162     HsWidgetPresentationData data;
   205     HsWidgetPresentationData data;
   165     data.zValue = zValue();
   208     data.zValue = zValue();
   166     data.widgetId = mDatabaseId;
   209     data.widgetId = mDatabaseId;
   167     return db->setWidgetPresentation(data);
   210     return db->setWidgetPresentation(data);
   168 }
   211 }
   169 
   212 
       
   213 /*!
       
   214     Saves the given presentation.
       
   215     Returns true on success, otherwise returns false.
       
   216 */
   170 bool HsWidgetHost::savePresentation(HsWidgetPresentationData &presentation)
   217 bool HsWidgetHost::savePresentation(HsWidgetPresentationData &presentation)
   171 {
   218 {
   172     HsDatabase *db = HsDatabase::instance();
   219     HsDatabase *db = HsDatabase::instance();
   173     
   220     
   174     presentation.widgetId = mDatabaseId;
   221     presentation.widgetId = mDatabaseId;
   175     return db->setWidgetPresentation(presentation);
   222     return db->setWidgetPresentation(presentation);
   176 }
   223 }
   177 
   224 
       
   225 /*!
       
   226     Fills the \a presentation based on the orientation field in 
       
   227     the given \a presentation. Returns true on success, otherwise 
       
   228     returns false.
       
   229 */
   178 bool HsWidgetHost::getPresentation(HsWidgetPresentationData &presentation)
   230 bool HsWidgetHost::getPresentation(HsWidgetPresentationData &presentation)
   179 {
   231 {
   180     HsDatabase *db = HsDatabase::instance();
   232     HsDatabase *db = HsDatabase::instance();
   181         
   233         
   182     presentation.widgetId = mDatabaseId;
   234     presentation.widgetId = mDatabaseId;
   183     return db->widgetPresentation(presentation);
   235     return db->widgetPresentation(presentation);
   184 }
   236 }
   185 
   237 
       
   238 /*!
       
   239     Removes the presentation for the given \a orientation.
       
   240     Returns true on success, otherwise returns false.
       
   241 */
   186 bool HsWidgetHost::removePresentation(Qt::Orientation orientation)
   242 bool HsWidgetHost::removePresentation(Qt::Orientation orientation)
   187 {
   243 {
   188     HsDatabase *db = HsDatabase::instance();
   244     HsDatabase *db = HsDatabase::instance();
   189     return db->deleteWidgetPresentation(mDatabaseId, orientation);
   245     return db->deleteWidgetPresentation(mDatabaseId, orientation);
   190 }
   246 }
   191 
   247 
       
   248 /*!
       
   249     Reimplemented from QGraphicsItem. Returns the shape of the
       
   250     this widget host. The shape is computed based on the contained
       
   251     widget.
       
   252 */
       
   253 QPainterPath HsWidgetHost::shape() const
       
   254 {
       
   255     QPainterPath path;
       
   256 
       
   257     if (mWidget) {
       
   258         QRectF currRect = rect();
       
   259         path = mWidget->shape();
       
   260 
       
   261         QRectF pathRect(path.boundingRect());
       
   262 
       
   263         if (pathRect.width() > currRect.width()
       
   264             || pathRect.height() > currRect.height()) {
       
   265             QPainterPath newPath(currRect.topLeft());
       
   266             newPath.addRect(currRect);
       
   267             path = path.intersected(newPath);
       
   268         }
       
   269     }
       
   270     return path;
       
   271 }
       
   272 
       
   273 /*!
       
   274     \fn HsWidgetHost::event_startAndShow()
       
   275     Initiates a transition to show state.
       
   276 */
       
   277 
       
   278 /*!
       
   279     \fn HsWidgetHost::event_startAndHide()
       
   280     Initiates a transition to hide state.
       
   281 */
       
   282 
       
   283 /*!
       
   284     \fn HsWidgetHost::event_unload()
       
   285     Initiates a transition to unloaded state.
       
   286 */
       
   287 
       
   288 /*!
       
   289     \fn HsWidgetHost::event_show()
       
   290     Initiates a transition to show state.
       
   291 */
       
   292 
       
   293 /*!
       
   294     \fn HsWidgetHost::event_hide()
       
   295     Initiates a transition to hide state.
       
   296 */
       
   297 
       
   298 /*!
       
   299     \fn HsWidgetHost::event_remove()
       
   300     Initiates a transition to remove state.
       
   301 */
       
   302 
       
   303 /*!
       
   304     \fn HsWidgetHost::event_close()
       
   305     Initiates a transition to final state.
       
   306 */
       
   307 
       
   308 /*!
       
   309     \fn HsWidgetHost::event_finished()
       
   310     Initiates a transition to finished state.
       
   311 */
       
   312 
       
   313 /*!
       
   314     \fn HsWidgetHost::event_faulted()
       
   315     Initiates a transition to faulted state.
       
   316 */
       
   317 
       
   318 /*!
       
   319     \fn HsWidgetHost::finished()
       
   320     Notifies the home screen framework that this widget
       
   321     host has moved to finished state.
       
   322 */
       
   323 
       
   324 /*!
       
   325     \fn HsWidgetHost::faulted()
       
   326     Notifies the home screen framework that this widget
       
   327     host has moved to faulted state.
       
   328 */
       
   329 
       
   330 /*!
       
   331     \fn HsWidgetHost::resized()
       
   332     Notifies the home screen framework that this widget
       
   333     host has resized itself.
       
   334 */
       
   335 
       
   336 /*!
       
   337     \fn HsWidgetHost::available()
       
   338     Notifies the home screen framework that this widget
       
   339     is now available.
       
   340 */
       
   341 
       
   342 /*!
       
   343     \fn HsWidgetHost::unavailable()
       
   344     Notifies the home screen framework that this widget
       
   345     is temporarily unavailable.
       
   346 */
       
   347 
       
   348 
       
   349 /*!
       
   350     Starts the widget. The \a show parameter defines the
       
   351     visibility of the widget.
       
   352 */
   192 void HsWidgetHost::startWidget(bool show)
   353 void HsWidgetHost::startWidget(bool show)
   193 {
   354 {
   194     if (!mStateMachine->isRunning()) {
   355     if (!mStateMachine->isRunning()) {
   195         mStateMachine->start();
   356         mStateMachine->start();
   196         // This is needed because QStateMachine::start() starts
   357         // This is needed because QStateMachine::start() starts
   204     } else {
   365     } else {
   205         emit event_startAndHide();
   366         emit event_startAndHide();
   206     }
   367     }
   207 }
   368 }
   208  
   369  
       
   370 /*!
       
   371     Puts the contained widget into show state.
       
   372 */
   209 void HsWidgetHost::showWidget()
   373 void HsWidgetHost::showWidget()
   210 {
   374 {
   211     emit event_show();
   375     emit event_show();
   212 }
   376 }
   213     
   377   
       
   378 /*!
       
   379     Puts the contained widget into hidden state.
       
   380 */
   214 void HsWidgetHost::hideWidget()
   381 void HsWidgetHost::hideWidget()
   215 {
   382 {
   216     emit event_hide();
   383     emit event_hide();
   217 }
   384 }
   218 
   385 
       
   386 /*!
       
   387     Notifies the conained widget about \a online
       
   388     status changes.
       
   389 */
   219 void HsWidgetHost::setOnline(bool online)
   390 void HsWidgetHost::setOnline(bool online)
   220 {
   391 {
   221     mIsOnlineProperty.write(mWidget, online);
   392     mIsOnlineProperty.write(mWidget, online);
   222 }
   393 }
   223 
   394 
       
   395 /*!
       
   396     Deletes this widget instance, including the 
       
   397     database entries.
       
   398 */
   224 void HsWidgetHost::remove()
   399 void HsWidgetHost::remove()
   225 {
   400 {
   226     if (mStateMachine->isRunning()) {
   401     if (mStateMachine->isRunning()) {
   227         emit event_remove();
   402         emit event_remove();
   228     } else {
   403     } else {
   229         action_remove();
   404         action_remove();
   230         deleteLater();
   405         deleteLater();
   231     }
   406     }
   232 }
   407 }
   233  
   408  
       
   409 /*!
       
   410     Deletes this widget instance, leaving the 
       
   411     database entries untouched.
       
   412 */
   234 void HsWidgetHost::close()
   413 void HsWidgetHost::close()
   235 {
   414 {
   236     if (mStateMachine->isRunning()) {
   415     if (mStateMachine->isRunning()) {
   237         emit event_close();
   416         emit event_close();
   238     } else {
   417     } else {
   239         deleteLater();
   418         deleteLater();
   240     }
   419     }
   241 }
   420 }
   242 
   421 
       
   422 /*!
       
   423     Starts the drag effect.
       
   424 */
   243 void HsWidgetHost::startDragEffect()
   425 void HsWidgetHost::startDragEffect()
   244 {
   426 {
   245     /* TODO: Uncomment after the Qt bug has been fixed.
   427     /* TODO: Uncomment after the Qt bug has been fixed.
   246     QGraphicsDropShadowEffect *effect =
   428     QGraphicsDropShadowEffect *effect =
   247         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   429         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   251     setTransformOriginPoint(rect().center());
   433     setTransformOriginPoint(rect().center());
   252 
   434 
   253     QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup();
   435     QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup();
   254 
   436 
   255     QPropertyAnimation *animation = new QPropertyAnimation(this, "scale");
   437     QPropertyAnimation *animation = new QPropertyAnimation(this, "scale");
   256     animation->setDuration(HsConfiguration::widgetDragEffectDuration());
   438     animation->setDuration(HSCONFIGURATION_GET(widgetDragEffectDuration));
   257     animation->setEndValue(1.1);
   439     animation->setEndValue(1.1);
   258     animationGroup->addAnimation(animation);
   440     animationGroup->addAnimation(animation);
   259 
   441 
   260     /* TODO: Uncomment after the Qt bug has been fixed.
   442     /* TODO: Uncomment after the Qt bug has been fixed.
   261     animation = new QPropertyAnimation(effect, "offset");
   443     animation = new QPropertyAnimation(effect, "offset");
   265     */
   447     */
   266 
   448 
   267     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   449     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   268 }
   450 }
   269 
   451 
       
   452 /*!
       
   453     Starts the drop effect.
       
   454 */
   270 void HsWidgetHost::startDropEffect()
   455 void HsWidgetHost::startDropEffect()
   271 {
   456 {
   272     /* TODO: Uncomment after the Qt bug has been fixed.
   457     /* TODO: Uncomment after the Qt bug has been fixed.
   273     QGraphicsDropShadowEffect *effect =
   458     QGraphicsDropShadowEffect *effect =
   274         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   459         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   276     HbInstantFeedback::play(HbFeedback::ItemDrop);
   461     HbInstantFeedback::play(HbFeedback::ItemDrop);
   277 
   462 
   278     QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup;
   463     QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup;
   279 
   464 
   280     QPropertyAnimation *animation = new QPropertyAnimation(this, "scale");
   465     QPropertyAnimation *animation = new QPropertyAnimation(this, "scale");
   281     animation->setDuration(HsConfiguration::widgetDropEffectDuration());
   466     animation->setDuration(HSCONFIGURATION_GET(widgetDropEffectDuration));
   282     animation->setEndValue(1);
   467     animation->setEndValue(1);
   283     animationGroup->addAnimation(animation);
   468     animationGroup->addAnimation(animation);
   284 
   469 
   285     /* TODO: Uncomment after the Qt bug has been fixed.
   470     /* TODO: Uncomment after the Qt bug has been fixed.
   286     animation = new QPropertyAnimation(effect, "offset");
   471     animation = new QPropertyAnimation(effect, "offset");
   290     */
   475     */
   291 
   476 
   292     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   477     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   293 }
   478 }
   294 
   479 
       
   480 /*!
       
   481     Reimplemented from QObject for monitoring changes in 
       
   482     contained widget's size.
       
   483 */
   295 bool HsWidgetHost::eventFilter(QObject *watched, QEvent *event)
   484 bool HsWidgetHost::eventFilter(QObject *watched, QEvent *event)
   296 {
   485 {
   297     if (event->type() == QEvent::GraphicsSceneResize ) {
   486     if (event->type() == QEvent::GraphicsSceneResize ) {
   298         QGraphicsSceneResizeEvent *resizeEvent = 
   487         QGraphicsSceneResizeEvent *resizeEvent = 
   299             static_cast<QGraphicsSceneResizeEvent *>(event);
   488             static_cast<QGraphicsSceneResizeEvent *>(event);
   301         emit resized();
   490         emit resized();
   302     }
   491     }
   303     return HbWidget::eventFilter(watched, event);
   492     return HbWidget::eventFilter(watched, event);
   304 }
   493 }
   305 
   494 
       
   495 /*!
       
   496     Reimplemented from HbWidget for pan gesture handling.
       
   497 */
       
   498 void HsWidgetHost::gestureEvent(QGestureEvent *event)
       
   499 {
       
   500     HsScene *scene = HsScene::instance();    
       
   501     QGesture *gesture = event->gesture(Qt::PanGesture);
       
   502     if (gesture) {
       
   503         switch (gesture->state()) {
       
   504             case Qt::GestureStarted:
       
   505                 grabMouse();
       
   506                 emit scene->pagePanStarted(event);
       
   507                 break;
       
   508             case Qt::GestureUpdated:
       
   509                 emit scene->pagePanUpdated(event);
       
   510                 break;
       
   511             case Qt::GestureFinished:
       
   512             case Qt::GestureCanceled:
       
   513                 ungrabMouse();
       
   514                 emit scene->pagePanFinished(event);
       
   515                 break;
       
   516             default:
       
   517                 break;
       
   518         }
       
   519     }
       
   520 }
       
   521 
       
   522 /*!
       
   523     \fn HsWidgetHost::mousePressEvent(QGraphicsSceneMouseEvent *)
       
   524     Reimplemented from QGraphicsItem for eating all mouse presses.
       
   525 */
       
   526 
       
   527 /*!
       
   528     Configures the touch are for this widget host.
       
   529 */
       
   530 void HsWidgetHost::setupTouchArea()
       
   531 {
       
   532     mTouchArea = new HsWidgetTouchArea(this);
       
   533     mTouchArea->setZValue(1);
       
   534 }
       
   535 
       
   536 /*!
       
   537     Configures the effects for this widget host.
       
   538 */
   306 void HsWidgetHost::setupEffects()
   539 void HsWidgetHost::setupEffects()
   307 {
   540 {
   308     /* TODO: Uncomment after the Qt bug has been fixed.
   541     /* TODO: Uncomment after the Qt bug has been fixed.
   309     QGraphicsDropShadowEffect *effect =
   542     QGraphicsDropShadowEffect *effect =
   310         new QGraphicsDropShadowEffect(this);
   543         new QGraphicsDropShadowEffect(this);
   313     effect->setOffset(3);
   546     effect->setOffset(3);
   314     setGraphicsEffect(effect);
   547     setGraphicsEffect(effect);
   315     */
   548     */
   316 }
   549 }
   317 
   550 
       
   551 /*!
       
   552     Configures the state machine for this widget host.
       
   553 */
   318 void HsWidgetHost::setupStates()
   554 void HsWidgetHost::setupStates()
   319 {
   555 {
   320     // State machine
   556     // State machine
   321 
   557 
   322     mStateMachine = new QStateMachine(this);
   558     mStateMachine = new QStateMachine(this);
   397 
   633 
   398     ENTRY_ACTION(state_finished, action_finished)
   634     ENTRY_ACTION(state_finished, action_finished)
   399 
   635 
   400     ENTRY_ACTION(state_faulted, action_faulted)
   636     ENTRY_ACTION(state_faulted, action_faulted)
   401 
   637 
       
   638     ENTRY_ACTION(state_remove, action_notifyRemove)
   402     ENTRY_ACTION(state_remove, action_remove)
   639     ENTRY_ACTION(state_remove, action_remove)
   403 
   640 
   404     // Delete on finish.
   641     // Delete on finish.
   405 
   642 
   406     connect(mStateMachine, SIGNAL(finished()), SLOT(deleteLater()), 
   643     connect(mStateMachine, SIGNAL(finished()), SLOT(deleteLater()), 
   407             Qt::QueuedConnection);
   644             Qt::QueuedConnection);
   408 }
   645 }
   409 
   646 
       
   647 /*!
       
   648     Assigns the meta \a property based on the given property \a name.
       
   649     Returns true on success, otherwise returns false.
       
   650 */
   410 bool HsWidgetHost::setProperty(const char *name, QMetaProperty &property)
   651 bool HsWidgetHost::setProperty(const char *name, QMetaProperty &property)
   411 {
   652 {
   412     const QMetaObject *object = mWidget->metaObject();
   653     const QMetaObject *object = mWidget->metaObject();
   413     int index = object->indexOfProperty(name);
   654     int index = object->indexOfProperty(name);
   414     property = object->property(index);
   655     property = object->property(index);
   415     return index >= 0;
   656     return index >= 0;
   416 }
   657 }
   417 
   658 
       
   659 /*!
       
   660     Assigns the meta \a method based on the given method \a signature.
       
   661     Returns true on success, otherwise returns false.
       
   662 */
   418 bool HsWidgetHost::setMethod(const char *signature, QMetaMethod &method)
   663 bool HsWidgetHost::setMethod(const char *signature, QMetaMethod &method)
   419 {
   664 {
   420     const QMetaObject *object = mWidget->metaObject();
   665     const QMetaObject *object = mWidget->metaObject();
   421     int index = object->indexOfMethod(
   666     int index = object->indexOfMethod(
   422         QMetaObject::normalizedSignature(signature));
   667         QMetaObject::normalizedSignature(signature));
   423     method = object->method(index);
   668     method = object->method(index);
   424     return index >= 0;
   669     return index >= 0;
   425 }
   670 }
   426 
   671 
       
   672 /*!
       
   673     Checks if the contained widget has implemented the
       
   674     signal with the given \a signature.
       
   675 */
   427 bool HsWidgetHost::hasSignal(const char *signature)
   676 bool HsWidgetHost::hasSignal(const char *signature)
   428 {
   677 {
   429     const QMetaObject *object = mWidget->metaObject();
   678     const QMetaObject *object = mWidget->metaObject();
   430     int index = object->indexOfSignal(
   679     int index = object->indexOfSignal(
   431         QMetaObject::normalizedSignature(signature));
   680         QMetaObject::normalizedSignature(signature));
   432     return index >= 0;
   681     return index >= 0;
   433 }
   682 }
   434 
   683 
       
   684 /*!
       
   685     Resizes this widget host to the given \a size.
       
   686 */
   435 void HsWidgetHost::setNewSize(const QSizeF &size)
   687 void HsWidgetHost::setNewSize(const QSizeF &size)
   436 {
   688 {
       
   689     mTouchArea->resize(size);
   437     resize(size);
   690     resize(size);
   438     setPreferredSize(size);
   691     setPreferredSize(size);
   439 }
   692 }
   440 
   693 
       
   694 /*!
       
   695     Assigns preferences for the contained widget.
       
   696     Returns true on success, otherwise returns false.
       
   697 */
   441 bool HsWidgetHost::setPreferencesToWidget()
   698 bool HsWidgetHost::setPreferencesToWidget()
   442 {
   699 {
   443     HsDatabase *db = HsDatabase::instance();
   700     HsDatabase *db = HsDatabase::instance();
   444     
   701     
   445     QVariantHash preferences;
   702     QVariantHash preferences;
   454     }
   711     }
   455 
   712 
   456     return true;
   713     return true;
   457 }
   714 }
   458 
   715 
       
   716 /*!
       
   717     Connects this widget host for monitoring changes
       
   718     in its widget component.
       
   719 */
   459 void HsWidgetHost::action_connectComponent()
   720 void HsWidgetHost::action_connectComponent()
   460 {
   721 {
   461     HsDatabase *db = HsDatabase::instance();
   722     HsDatabase *db = HsDatabase::instance();
   462     
   723     
   463     HsWidgetData data;
   724     HsWidgetData data;
   475     connect(mComponent, SIGNAL(unavailable()), SIGNAL(unavailable()));
   736     connect(mComponent, SIGNAL(unavailable()), SIGNAL(unavailable()));
   476     connect(mComponent, SIGNAL(available()), SIGNAL(available()));
   737     connect(mComponent, SIGNAL(available()), SIGNAL(available()));
   477     connect(mComponent, SIGNAL(updated()), SIGNAL(available()));
   738     connect(mComponent, SIGNAL(updated()), SIGNAL(available()));
   478 }
   739 }
   479 
   740 
       
   741 /*!
       
   742     Disconnects this widget host from its widget component.
       
   743 */
   480 void HsWidgetHost::action_disconnectComponent()
   744 void HsWidgetHost::action_disconnectComponent()
   481 {
   745 {
   482     mComponent->disconnect(this);
   746     mComponent->disconnect(this);
   483 }
   747 }
   484 
   748 
       
   749 /*!
       
   750     Loads the contained widget from a widget plugin and 
       
   751     connects to it's meta interface.
       
   752 */
   485 void HsWidgetHost::action_load()
   753 void HsWidgetHost::action_load()
   486 {
   754 {
   487     QServiceManager manager;
   755     QServiceManager manager;
   488     QServiceFilter filter("com.nokia.symbian.IHomeScreenWidget");
   756     QServiceFilter filter("com.nokia.symbian.IHomeScreenWidget");
   489     filter.setServiceName(mComponent->uri());
   757     filter.setServiceName(mComponent->uri());
   505         return;
   773         return;
   506     }
   774     }
   507 
   775 
   508     setMethod("onInitialize()", mOnInitializeMethod);
   776     setMethod("onInitialize()", mOnInitializeMethod);
   509     setMethod("onUninitialize()", mOnUninitializeMethod);
   777     setMethod("onUninitialize()", mOnUninitializeMethod);
   510     setMethod("isPannable(QGraphicsSceneMouseEvent*)", mIsPannableMethod);
   778     
   511 
       
   512     setProperty("isOnline", mIsOnlineProperty);
   779     setProperty("isOnline", mIsOnlineProperty);
   513 	setProperty("rootPath", mRootPathProperty);
   780 	setProperty("rootPath", mRootPathProperty);
   514     
   781     
   515     if (hasSignal("setPreferences(const QStringList&)")) {
   782     if (hasSignal("setPreferences(const QStringList&)")) {
   516         connect(mWidget, SIGNAL(setPreferences(QStringList)),
   783         connect(mWidget, SIGNAL(setPreferences(QStringList)),
   517                 SLOT(onSetPreferences(QStringList)));
   784             SLOT(onSetPreferences(QStringList)), Qt::QueuedConnection);
   518     }
   785     }
   519     if (hasSignal("finished()")) {
   786     if (hasSignal("finished()")) {
   520         connect(mWidget, SIGNAL(finished()),
   787         connect(mWidget, SIGNAL(finished()),
   521                 SLOT(onFinished()));
   788             SLOT(onFinished()), Qt::QueuedConnection);
   522     }
   789     }
   523     if (hasSignal("error()")) {
   790     if (hasSignal("error()")) {
   524         connect(mWidget, SIGNAL(error()),
   791         connect(mWidget, SIGNAL(error()),
   525                 SLOT(onError()));
   792             SLOT(onError()), Qt::QueuedConnection);
   526     }
   793     }
   527 
   794 
   528     mWidget->installEventFilter(this);
   795     mWidget->installEventFilter(this);
   529 
   796 
   530     HsScene *scene = HsScene::instance();
   797     setMinimumSize(HSCONFIGURATION_GET(minimumWidgetSizeInPixels));
   531     setMaximumSize(scene->maximumWidgetSizeInPixels());
   798     setMaximumSize(HSCONFIGURATION_GET(maximumWidgetSizeInPixels));
   532     setMinimumSize(scene->minimumWidgetSizeInPixels());
   799     
   533 
       
   534     loadPresentation();
   800     loadPresentation();
   535 
   801 
   536     mWidget->setParentItem(this);
   802     mWidget->setParentItem(this);
   537 
   803 
   538     setNewSize(mWidget->size());
   804     setNewSize(mWidget->size());
   539 }
   805 
   540 
   806     QString objName(mComponent->uri());
       
   807     objName.append(":");
       
   808     objName.append(QString::number(mDatabaseId));
       
   809     setObjectName(objName);
       
   810 }
       
   811 
       
   812 /*!
       
   813     Unloads the contained widget. 
       
   814 */
   541 void HsWidgetHost::action_unload()
   815 void HsWidgetHost::action_unload()
   542 {
   816 {
   543     delete mWidget;
   817     delete mWidget;
   544     mWidget = 0;
   818     mWidget = 0;
   545 
   819 		// This is needed because QServicePluginCleanup is 
       
   820     // deleted asynchronously via the eventloop (deleteLater). 
       
   821     // Here we want the plugin to unload synchronously.
       
   822     QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
       
   823     	
   546     mOnInitializeMethod = QMetaMethod();
   824     mOnInitializeMethod = QMetaMethod();
   547     mOnShowMethod = QMetaMethod();
   825     mOnShowMethod = QMetaMethod();
   548     mOnHideMethod = QMetaMethod();
   826     mOnHideMethod = QMetaMethod();
   549     mOnUninitializeMethod = QMetaMethod();
   827     mOnUninitializeMethod = QMetaMethod();    
   550     mIsPannableMethod = QMetaMethod();
       
   551     mIsOnlineProperty = QMetaProperty();
   828     mIsOnlineProperty = QMetaProperty();
   552 	mRootPathProperty = QMetaProperty();    
   829 	mRootPathProperty = QMetaProperty();    
   553 }
   830 }
   554 
   831 
       
   832 /*!
       
   833     Initializes the contained widget.
       
   834 */
   555 void HsWidgetHost::action_initialize()
   835 void HsWidgetHost::action_initialize()
   556 {    
   836 {    
   557     mRootPathProperty.write(mWidget, mComponent->rootPath());
   837     mRootPathProperty.write(mWidget, mComponent->rootPath());
   558     setPreferencesToWidget();
   838     setPreferencesToWidget();
   559     setOnline(HsScene::instance()->isOnline());
   839     setOnline(HsScene::instance()->isOnline());
   560     mOnInitializeMethod.invoke(mWidget);
   840     mOnInitializeMethod.invoke(mWidget);
   561 }
   841 }
   562 
   842 
       
   843 /*!
       
   844     Uninitializes the contained widget.
       
   845 */
   563 void HsWidgetHost::action_uninitialize()
   846 void HsWidgetHost::action_uninitialize()
   564 {
   847 {
   565     mOnUninitializeMethod.invoke(mWidget);
   848     mOnUninitializeMethod.invoke(mWidget);
   566 }
   849 }
   567 
   850 
       
   851 /*!
       
   852     Puts the contained widget into show state.
       
   853 */
   568 void HsWidgetHost::action_show()
   854 void HsWidgetHost::action_show()
   569 {
   855 {
   570     if (!mIsFinishing) {
   856     if (!mIsFinishing) {
   571         mOnShowMethod.invoke(mWidget);
   857         mOnShowMethod.invoke(mWidget);
   572     }
   858     }
   573 }
   859 }
   574 
   860 
       
   861 /*!
       
   862     Puts the contained widget into hidden state.
       
   863 */
   575 void HsWidgetHost::action_hide()
   864 void HsWidgetHost::action_hide()
   576 {
   865 {
   577     if (!mIsFinishing) {
   866     if (!mIsFinishing) {
   578         mOnHideMethod.invoke(mWidget);
   867         mOnHideMethod.invoke(mWidget);
   579     }
   868     }
   580 }
   869 }
   581 
   870 
       
   871 /*!
       
   872     Notifies the home screen framework that this widget
       
   873     host has moved to finished state.
       
   874 */
   582 void HsWidgetHost::action_finished()
   875 void HsWidgetHost::action_finished()
   583 {
   876 {
   584     emit finished();
   877     emit finished();
   585 }
   878 }
   586 
   879 
       
   880 /*!
       
   881     Notifies the home screen framework that this widget
       
   882     host has moved to faulted state.
       
   883 */
   587 void HsWidgetHost::action_faulted()
   884 void HsWidgetHost::action_faulted()
   588 {
   885 {
   589     emit faulted();
   886     emit faulted();
   590 }
   887 }
   591 
   888 
       
   889 /*!
       
   890     Removes the contained widget from the home screen
       
   891     database.
       
   892 */
   592 void HsWidgetHost::action_remove()
   893 void HsWidgetHost::action_remove()
   593 {
   894 {
   594     HsDatabase *db = HsDatabase::instance();
   895     HsDatabase *db = HsDatabase::instance();
   595     
   896     
   596     db->deleteWidget(mDatabaseId);
   897     db->deleteWidget(mDatabaseId);
   597     mDatabaseId = -1;
   898     mDatabaseId = -1;
   598 }
   899 }
   599 
   900 
       
   901 /*!
       
   902     Notifies the widget removal through the content service.
       
   903 */
       
   904 void HsWidgetHost::action_notifyRemove()
       
   905 {
       
   906     HsDatabase *db = HsDatabase::instance();
       
   907     QVariantHash preferences;
       
   908     db->widgetPreferences(mDatabaseId, preferences);
       
   909     HsContentService::instance()->emitWidgetRemoved(mComponent->uri(), preferences);
       
   910 }
       
   911 
       
   912 /*!
       
   913     Handles contained widget's finished event.
       
   914     Moves this widget host to finished state.
       
   915 */
   600 void HsWidgetHost::onFinished()
   916 void HsWidgetHost::onFinished()
   601 {
   917 {
   602     mIsFinishing = true;
   918     mIsFinishing = true;
   603     emit event_finished();
   919     emit event_finished();
   604 }
   920 }
   605  
   921  
       
   922 /*!
       
   923     Handles contained widget's error event.
       
   924     Moves this widget host to faulted state.
       
   925 */
   606 void HsWidgetHost::onError()
   926 void HsWidgetHost::onError()
   607 {
   927 {
   608     mIsFinishing = true;
   928     mIsFinishing = true;
   609     emit event_faulted();
   929     emit event_faulted();
   610 }
   930 }
   611 
   931 
       
   932 /*!
       
   933     Handles contained widget's setPreferences event.
       
   934     Stores the preferences for the given \a names to
       
   935     the home screen database.
       
   936 */
   612 void HsWidgetHost::onSetPreferences(const QStringList &names)
   937 void HsWidgetHost::onSetPreferences(const QStringList &names)
   613 {
   938 {
   614     if (names.isEmpty()) {
   939     if (names.isEmpty()) {
   615         return;
   940         return;
   616     }
   941     }