homescreenapp/hsdomainmodel/src/hswidgethost.cpp
changeset 61 2b1b11a301d2
parent 60 30f14686fb04
child 77 4b195f3bea29
equal deleted inserted replaced
60:30f14686fb04 61:2b1b11a301d2
    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) \
    52 
    55 
    53 
    56 
    54 /*!
    57 /*!
    55     \class HsWidgetHost
    58     \class HsWidgetHost
    56     \ingroup group_hsdomainmodel
    59     \ingroup group_hsdomainmodel
    57     \brief 
    60     \brief Each widget is controlled by the home screen framework through a widget host.
    58 */
    61 */
    59 
    62 
    60 /*!
    63 /*!
    61 
    64     Constructs a new widget host with given \a databaseId and
       
    65     \a parent item.
    62 */
    66 */
    63 HsWidgetHost::HsWidgetHost(int databaseId, QGraphicsItem *parent)
    67 HsWidgetHost::HsWidgetHost(int databaseId, QGraphicsItem *parent)
    64   : HbWidget(parent),
    68   : HbWidget(parent),
    65     mDatabaseId(databaseId),
    69     mDatabaseId(databaseId),
    66     mStateMachine(0),
    70     mStateMachine(0),
    76     grabGesture(Qt::TapAndHoldGesture);
    80     grabGesture(Qt::TapAndHoldGesture);
    77     grabGesture(Qt::PanGesture);
    81     grabGesture(Qt::PanGesture);
    78     grabGesture(Qt::PinchGesture);
    82     grabGesture(Qt::PinchGesture);
    79     grabGesture(Qt::SwipeGesture);
    83     grabGesture(Qt::SwipeGesture);
    80     grabGesture(Qt::CustomGesture);
    84     grabGesture(Qt::CustomGesture);
    81 
    85     
       
    86     setupTouchArea();
    82     setupEffects();
    87     setupEffects();
    83     setupStates();
    88     setupStates();
    84 }
    89 }
    85 
    90 
       
    91 /*!
       
    92     Destructor.
       
    93 */
    86 HsWidgetHost::~HsWidgetHost()
    94 HsWidgetHost::~HsWidgetHost()
    87 {
    95 {
    88 }
    96 }
    89 
    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 */
    90 HsWidgetHost *HsWidgetHost::createInstance(HsWidgetData &widgetData, 
   103 HsWidgetHost *HsWidgetHost::createInstance(HsWidgetData &widgetData, 
    91                                            const QVariantHash &preferences)
   104                                            const QVariantHash &preferences)
    92 {
   105 {
    93     HsDatabase *db = HsDatabase::instance();
   106     HsDatabase *db = HsDatabase::instance();
    94 
   107 
    98     } else {
   111     } else {
    99         return 0;
   112         return 0;
   100     }
   113     }
   101 }
   114 }
   102 
   115 
       
   116 /*!
       
   117     Returns the databaseId.
       
   118 */
   103 int HsWidgetHost::databaseId() const
   119 int HsWidgetHost::databaseId() const
   104 {
   120 {
   105     return mDatabaseId;
   121     return mDatabaseId;
   106 }
   122 }
   107 
   123 
       
   124 /*!
       
   125     Sets the containing \a page for this widget host.
       
   126     Returns true on success, otherwise returns false.
       
   127 */
   108 bool HsWidgetHost::setPage(HsPage *page)
   128 bool HsWidgetHost::setPage(HsPage *page)
   109 {
   129 {
   110     HsDatabase *db = HsDatabase::instance();
   130     HsDatabase *db = HsDatabase::instance();
   111     
   131     
   112     HsWidgetData data;
   132     HsWidgetData data;
   126 
   146 
   127     mPage = page;
   147     mPage = page;
   128     return true;
   148     return true;
   129 }
   149 }
   130  
   150  
       
   151 /*!
       
   152     Returns the containing page for this widget. Returns 0 
       
   153     if this widget has no containg page.
       
   154 */
   131 HsPage *HsWidgetHost::page() const
   155 HsPage *HsWidgetHost::page() const
   132 {
   156 {
   133     return mPage;
   157     return mPage;
   134 }
   158 }
   135 
   159 
   136 bool HsWidgetHost::isPannable(QGraphicsSceneMouseEvent *event)
   160 /*!
   137 {
   161     Loads presentation based on the current orientation.
   138     bool result = false;
   162     Returns true on success, otherwise returns false.
   139     mIsPannableMethod.invoke(mWidget, Q_RETURN_ARG(bool, result), Q_ARG(QGraphicsSceneMouseEvent *,event));
   163 */
   140     return result;
       
   141 }
       
   142 
       
   143 bool HsWidgetHost::loadPresentation()
   164 bool HsWidgetHost::loadPresentation()
   144 {
   165 {
   145     return loadPresentation(HsScene::orientation());
   166     return loadPresentation(HsScene::orientation());
   146 }
   167 }
   147 
   168 
       
   169 /*!
       
   170     Loads presentation based on the given \a orientation.
       
   171     Returns true on success, otherwise returns false.
       
   172 */
   148 bool HsWidgetHost::loadPresentation(Qt::Orientation orientation)
   173 bool HsWidgetHost::loadPresentation(Qt::Orientation orientation)
   149 {
   174 {
   150     HsDatabase *db = HsDatabase::instance();
   175     HsDatabase *db = HsDatabase::instance();
   151         
   176         
   152     HsWidgetPresentationData data;
   177     HsWidgetPresentationData data;
   158     setPos(data.x, data.y);
   183     setPos(data.x, data.y);
   159     setZValue(data.zValue);
   184     setZValue(data.zValue);
   160     return true;
   185     return true;
   161 }
   186 }
   162 
   187 
       
   188 /*!
       
   189     Saves the current presentation.
       
   190     Returns true on success, otherwise returns false.
       
   191 */
   163 bool HsWidgetHost::savePresentation()
   192 bool HsWidgetHost::savePresentation()
   164 {
   193 {
   165     return savePresentation(HsScene::orientation());
   194     return savePresentation(HsScene::orientation());
   166 }
   195 }
   167 
   196 
       
   197 /*!
       
   198     Saves the current presentation for the given \a orientation.
       
   199     Returns true on success, otherwise returns false.
       
   200 */
   168 bool HsWidgetHost::savePresentation(Qt::Orientation orientation)
   201 bool HsWidgetHost::savePresentation(Qt::Orientation orientation)
   169 {
   202 {
   170     HsDatabase *db = HsDatabase::instance();
   203     HsDatabase *db = HsDatabase::instance();
   171         
   204         
   172     HsWidgetPresentationData data;
   205     HsWidgetPresentationData data;
   175     data.zValue = zValue();
   208     data.zValue = zValue();
   176     data.widgetId = mDatabaseId;
   209     data.widgetId = mDatabaseId;
   177     return db->setWidgetPresentation(data);
   210     return db->setWidgetPresentation(data);
   178 }
   211 }
   179 
   212 
       
   213 /*!
       
   214     Saves the given presentation.
       
   215     Returns true on success, otherwise returns false.
       
   216 */
   180 bool HsWidgetHost::savePresentation(HsWidgetPresentationData &presentation)
   217 bool HsWidgetHost::savePresentation(HsWidgetPresentationData &presentation)
   181 {
   218 {
   182     HsDatabase *db = HsDatabase::instance();
   219     HsDatabase *db = HsDatabase::instance();
   183     
   220     
   184     presentation.widgetId = mDatabaseId;
   221     presentation.widgetId = mDatabaseId;
   185     return db->setWidgetPresentation(presentation);
   222     return db->setWidgetPresentation(presentation);
   186 }
   223 }
   187 
   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 */
   188 bool HsWidgetHost::getPresentation(HsWidgetPresentationData &presentation)
   230 bool HsWidgetHost::getPresentation(HsWidgetPresentationData &presentation)
   189 {
   231 {
   190     HsDatabase *db = HsDatabase::instance();
   232     HsDatabase *db = HsDatabase::instance();
   191         
   233         
   192     presentation.widgetId = mDatabaseId;
   234     presentation.widgetId = mDatabaseId;
   193     return db->widgetPresentation(presentation);
   235     return db->widgetPresentation(presentation);
   194 }
   236 }
   195 
   237 
       
   238 /*!
       
   239     Removes the presentation for the given \a orientation.
       
   240     Returns true on success, otherwise returns false.
       
   241 */
   196 bool HsWidgetHost::removePresentation(Qt::Orientation orientation)
   242 bool HsWidgetHost::removePresentation(Qt::Orientation orientation)
   197 {
   243 {
   198     HsDatabase *db = HsDatabase::instance();
   244     HsDatabase *db = HsDatabase::instance();
   199     return db->deleteWidgetPresentation(mDatabaseId, orientation);
   245     return db->deleteWidgetPresentation(mDatabaseId, orientation);
   200 }
   246 }
   201 
   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 */
   202 void HsWidgetHost::startWidget(bool show)
   353 void HsWidgetHost::startWidget(bool show)
   203 {
   354 {
   204     if (!mStateMachine->isRunning()) {
   355     if (!mStateMachine->isRunning()) {
   205         mStateMachine->start();
   356         mStateMachine->start();
   206         // This is needed because QStateMachine::start() starts
   357         // This is needed because QStateMachine::start() starts
   214     } else {
   365     } else {
   215         emit event_startAndHide();
   366         emit event_startAndHide();
   216     }
   367     }
   217 }
   368 }
   218  
   369  
       
   370 /*!
       
   371     Puts the contained widget into show state.
       
   372 */
   219 void HsWidgetHost::showWidget()
   373 void HsWidgetHost::showWidget()
   220 {
   374 {
   221     emit event_show();
   375     emit event_show();
   222 }
   376 }
   223     
   377   
       
   378 /*!
       
   379     Puts the contained widget into hidden state.
       
   380 */
   224 void HsWidgetHost::hideWidget()
   381 void HsWidgetHost::hideWidget()
   225 {
   382 {
   226     emit event_hide();
   383     emit event_hide();
   227 }
   384 }
   228 
   385 
       
   386 /*!
       
   387     Notifies the conained widget about \a online
       
   388     status changes.
       
   389 */
   229 void HsWidgetHost::setOnline(bool online)
   390 void HsWidgetHost::setOnline(bool online)
   230 {
   391 {
   231     mIsOnlineProperty.write(mWidget, online);
   392     mIsOnlineProperty.write(mWidget, online);
   232 }
   393 }
   233 
   394 
       
   395 /*!
       
   396     Deletes this widget instance, including the 
       
   397     database entries.
       
   398 */
   234 void HsWidgetHost::remove()
   399 void HsWidgetHost::remove()
   235 {
   400 {
   236     if (mStateMachine->isRunning()) {
   401     if (mStateMachine->isRunning()) {
   237         emit event_remove();
   402         emit event_remove();
   238     } else {
   403     } else {
   239         action_remove();
   404         action_remove();
   240         deleteLater();
   405         deleteLater();
   241     }
   406     }
   242 }
   407 }
   243  
   408  
       
   409 /*!
       
   410     Deletes this widget instance, leaving the 
       
   411     database entries untouched.
       
   412 */
   244 void HsWidgetHost::close()
   413 void HsWidgetHost::close()
   245 {
   414 {
   246     if (mStateMachine->isRunning()) {
   415     if (mStateMachine->isRunning()) {
   247         emit event_close();
   416         emit event_close();
   248     } else {
   417     } else {
   249         deleteLater();
   418         deleteLater();
   250     }
   419     }
   251 }
   420 }
   252 
   421 
       
   422 /*!
       
   423     Starts the drag effect.
       
   424 */
   253 void HsWidgetHost::startDragEffect()
   425 void HsWidgetHost::startDragEffect()
   254 {
   426 {
   255     /* TODO: Uncomment after the Qt bug has been fixed.
   427     /* TODO: Uncomment after the Qt bug has been fixed.
   256     QGraphicsDropShadowEffect *effect =
   428     QGraphicsDropShadowEffect *effect =
   257         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   429         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   275     */
   447     */
   276 
   448 
   277     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   449     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   278 }
   450 }
   279 
   451 
       
   452 /*!
       
   453     Starts the drop effect.
       
   454 */
   280 void HsWidgetHost::startDropEffect()
   455 void HsWidgetHost::startDropEffect()
   281 {
   456 {
   282     /* TODO: Uncomment after the Qt bug has been fixed.
   457     /* TODO: Uncomment after the Qt bug has been fixed.
   283     QGraphicsDropShadowEffect *effect =
   458     QGraphicsDropShadowEffect *effect =
   284         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   459         static_cast<QGraphicsDropShadowEffect *>(graphicsEffect());
   300     */
   475     */
   301 
   476 
   302     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   477     animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
   303 }
   478 }
   304 
   479 
       
   480 /*!
       
   481     Reimplemented from QObject for monitoring changes in 
       
   482     contained widget's size.
       
   483 */
   305 bool HsWidgetHost::eventFilter(QObject *watched, QEvent *event)
   484 bool HsWidgetHost::eventFilter(QObject *watched, QEvent *event)
   306 {
   485 {
   307     if (event->type() == QEvent::GraphicsSceneResize ) {
   486     if (event->type() == QEvent::GraphicsSceneResize ) {
   308         QGraphicsSceneResizeEvent *resizeEvent = 
   487         QGraphicsSceneResizeEvent *resizeEvent = 
   309             static_cast<QGraphicsSceneResizeEvent *>(event);
   488             static_cast<QGraphicsSceneResizeEvent *>(event);
   311         emit resized();
   490         emit resized();
   312     }
   491     }
   313     return HbWidget::eventFilter(watched, event);
   492     return HbWidget::eventFilter(watched, event);
   314 }
   493 }
   315 
   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 */
   316 void HsWidgetHost::setupEffects()
   539 void HsWidgetHost::setupEffects()
   317 {
   540 {
   318     /* TODO: Uncomment after the Qt bug has been fixed.
   541     /* TODO: Uncomment after the Qt bug has been fixed.
   319     QGraphicsDropShadowEffect *effect =
   542     QGraphicsDropShadowEffect *effect =
   320         new QGraphicsDropShadowEffect(this);
   543         new QGraphicsDropShadowEffect(this);
   323     effect->setOffset(3);
   546     effect->setOffset(3);
   324     setGraphicsEffect(effect);
   547     setGraphicsEffect(effect);
   325     */
   548     */
   326 }
   549 }
   327 
   550 
       
   551 /*!
       
   552     Configures the state machine for this widget host.
       
   553 */
   328 void HsWidgetHost::setupStates()
   554 void HsWidgetHost::setupStates()
   329 {
   555 {
   330     // State machine
   556     // State machine
   331 
   557 
   332     mStateMachine = new QStateMachine(this);
   558     mStateMachine = new QStateMachine(this);
   407 
   633 
   408     ENTRY_ACTION(state_finished, action_finished)
   634     ENTRY_ACTION(state_finished, action_finished)
   409 
   635 
   410     ENTRY_ACTION(state_faulted, action_faulted)
   636     ENTRY_ACTION(state_faulted, action_faulted)
   411 
   637 
       
   638     ENTRY_ACTION(state_remove, action_notifyRemove)
   412     ENTRY_ACTION(state_remove, action_remove)
   639     ENTRY_ACTION(state_remove, action_remove)
   413 
   640 
   414     // Delete on finish.
   641     // Delete on finish.
   415 
   642 
   416     connect(mStateMachine, SIGNAL(finished()), SLOT(deleteLater()), 
   643     connect(mStateMachine, SIGNAL(finished()), SLOT(deleteLater()), 
   417             Qt::QueuedConnection);
   644             Qt::QueuedConnection);
   418 }
   645 }
   419 
   646 
       
   647 /*!
       
   648     Assigns the meta \a property based on the given property \a name.
       
   649     Returns true on success, otherwise returns false.
       
   650 */
   420 bool HsWidgetHost::setProperty(const char *name, QMetaProperty &property)
   651 bool HsWidgetHost::setProperty(const char *name, QMetaProperty &property)
   421 {
   652 {
   422     const QMetaObject *object = mWidget->metaObject();
   653     const QMetaObject *object = mWidget->metaObject();
   423     int index = object->indexOfProperty(name);
   654     int index = object->indexOfProperty(name);
   424     property = object->property(index);
   655     property = object->property(index);
   425     return index >= 0;
   656     return index >= 0;
   426 }
   657 }
   427 
   658 
       
   659 /*!
       
   660     Assigns the meta \a method based on the given method \a signature.
       
   661     Returns true on success, otherwise returns false.
       
   662 */
   428 bool HsWidgetHost::setMethod(const char *signature, QMetaMethod &method)
   663 bool HsWidgetHost::setMethod(const char *signature, QMetaMethod &method)
   429 {
   664 {
   430     const QMetaObject *object = mWidget->metaObject();
   665     const QMetaObject *object = mWidget->metaObject();
   431     int index = object->indexOfMethod(
   666     int index = object->indexOfMethod(
   432         QMetaObject::normalizedSignature(signature));
   667         QMetaObject::normalizedSignature(signature));
   433     method = object->method(index);
   668     method = object->method(index);
   434     return index >= 0;
   669     return index >= 0;
   435 }
   670 }
   436 
   671 
       
   672 /*!
       
   673     Checks if the contained widget has implemented the
       
   674     signal with the given \a signature.
       
   675 */
   437 bool HsWidgetHost::hasSignal(const char *signature)
   676 bool HsWidgetHost::hasSignal(const char *signature)
   438 {
   677 {
   439     const QMetaObject *object = mWidget->metaObject();
   678     const QMetaObject *object = mWidget->metaObject();
   440     int index = object->indexOfSignal(
   679     int index = object->indexOfSignal(
   441         QMetaObject::normalizedSignature(signature));
   680         QMetaObject::normalizedSignature(signature));
   442     return index >= 0;
   681     return index >= 0;
   443 }
   682 }
   444 
   683 
       
   684 /*!
       
   685     Resizes this widget host to the given \a size.
       
   686 */
   445 void HsWidgetHost::setNewSize(const QSizeF &size)
   687 void HsWidgetHost::setNewSize(const QSizeF &size)
   446 {
   688 {
       
   689     mTouchArea->resize(size);
   447     resize(size);
   690     resize(size);
   448     setPreferredSize(size);
   691     setPreferredSize(size);
   449 }
   692 }
   450 
   693 
       
   694 /*!
       
   695     Assigns preferences for the contained widget.
       
   696     Returns true on success, otherwise returns false.
       
   697 */
   451 bool HsWidgetHost::setPreferencesToWidget()
   698 bool HsWidgetHost::setPreferencesToWidget()
   452 {
   699 {
   453     HsDatabase *db = HsDatabase::instance();
   700     HsDatabase *db = HsDatabase::instance();
   454     
   701     
   455     QVariantHash preferences;
   702     QVariantHash preferences;
   464     }
   711     }
   465 
   712 
   466     return true;
   713     return true;
   467 }
   714 }
   468 
   715 
       
   716 /*!
       
   717     Connects this widget host for monitoring changes
       
   718     in its widget component.
       
   719 */
   469 void HsWidgetHost::action_connectComponent()
   720 void HsWidgetHost::action_connectComponent()
   470 {
   721 {
   471     HsDatabase *db = HsDatabase::instance();
   722     HsDatabase *db = HsDatabase::instance();
   472     
   723     
   473     HsWidgetData data;
   724     HsWidgetData data;
   485     connect(mComponent, SIGNAL(unavailable()), SIGNAL(unavailable()));
   736     connect(mComponent, SIGNAL(unavailable()), SIGNAL(unavailable()));
   486     connect(mComponent, SIGNAL(available()), SIGNAL(available()));
   737     connect(mComponent, SIGNAL(available()), SIGNAL(available()));
   487     connect(mComponent, SIGNAL(updated()), SIGNAL(available()));
   738     connect(mComponent, SIGNAL(updated()), SIGNAL(available()));
   488 }
   739 }
   489 
   740 
       
   741 /*!
       
   742     Disconnects this widget host from its widget component.
       
   743 */
   490 void HsWidgetHost::action_disconnectComponent()
   744 void HsWidgetHost::action_disconnectComponent()
   491 {
   745 {
   492     mComponent->disconnect(this);
   746     mComponent->disconnect(this);
   493 }
   747 }
   494 
   748 
       
   749 /*!
       
   750     Loads the contained widget from a widget plugin and 
       
   751     connects to it's meta interface.
       
   752 */
   495 void HsWidgetHost::action_load()
   753 void HsWidgetHost::action_load()
   496 {
   754 {
   497     QServiceManager manager;
   755     QServiceManager manager;
   498     QServiceFilter filter("com.nokia.symbian.IHomeScreenWidget");
   756     QServiceFilter filter("com.nokia.symbian.IHomeScreenWidget");
   499     filter.setServiceName(mComponent->uri());
   757     filter.setServiceName(mComponent->uri());
   515         return;
   773         return;
   516     }
   774     }
   517 
   775 
   518     setMethod("onInitialize()", mOnInitializeMethod);
   776     setMethod("onInitialize()", mOnInitializeMethod);
   519     setMethod("onUninitialize()", mOnUninitializeMethod);
   777     setMethod("onUninitialize()", mOnUninitializeMethod);
   520     setMethod("isPannable(QGraphicsSceneMouseEvent*)", mIsPannableMethod);
   778     
   521 
       
   522     setProperty("isOnline", mIsOnlineProperty);
   779     setProperty("isOnline", mIsOnlineProperty);
   523 	setProperty("rootPath", mRootPathProperty);
   780 	setProperty("rootPath", mRootPathProperty);
   524     
   781     
   525     if (hasSignal("setPreferences(const QStringList&)")) {
   782     if (hasSignal("setPreferences(const QStringList&)")) {
   526         connect(mWidget, SIGNAL(setPreferences(QStringList)),
   783         connect(mWidget, SIGNAL(setPreferences(QStringList)),
   527                 SLOT(onSetPreferences(QStringList)));
   784             SLOT(onSetPreferences(QStringList)), Qt::QueuedConnection);
   528     }
   785     }
   529     if (hasSignal("finished()")) {
   786     if (hasSignal("finished()")) {
   530         connect(mWidget, SIGNAL(finished()),
   787         connect(mWidget, SIGNAL(finished()),
   531                 SLOT(onFinished()));
   788             SLOT(onFinished()), Qt::QueuedConnection);
   532     }
   789     }
   533     if (hasSignal("error()")) {
   790     if (hasSignal("error()")) {
   534         connect(mWidget, SIGNAL(error()),
   791         connect(mWidget, SIGNAL(error()),
   535                 SLOT(onError()));
   792             SLOT(onError()), Qt::QueuedConnection);
   536     }
   793     }
   537 
   794 
   538     mWidget->installEventFilter(this);
   795     mWidget->installEventFilter(this);
   539 
   796 
   540     setMinimumSize(HSCONFIGURATION_GET(minimumWidgetSizeInPixels));
   797     setMinimumSize(HSCONFIGURATION_GET(minimumWidgetSizeInPixels));
   543     loadPresentation();
   800     loadPresentation();
   544 
   801 
   545     mWidget->setParentItem(this);
   802     mWidget->setParentItem(this);
   546 
   803 
   547     setNewSize(mWidget->size());
   804     setNewSize(mWidget->size());
   548 }
   805 
   549 
   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 */
   550 void HsWidgetHost::action_unload()
   815 void HsWidgetHost::action_unload()
   551 {
   816 {
   552     delete mWidget;
   817     delete mWidget;
   553     mWidget = 0;
   818     mWidget = 0;
   554 
   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     	
   555     mOnInitializeMethod = QMetaMethod();
   824     mOnInitializeMethod = QMetaMethod();
   556     mOnShowMethod = QMetaMethod();
   825     mOnShowMethod = QMetaMethod();
   557     mOnHideMethod = QMetaMethod();
   826     mOnHideMethod = QMetaMethod();
   558     mOnUninitializeMethod = QMetaMethod();
   827     mOnUninitializeMethod = QMetaMethod();    
   559     mIsPannableMethod = QMetaMethod();
       
   560     mIsOnlineProperty = QMetaProperty();
   828     mIsOnlineProperty = QMetaProperty();
   561 	mRootPathProperty = QMetaProperty();    
   829 	mRootPathProperty = QMetaProperty();    
   562 }
   830 }
   563 
   831 
       
   832 /*!
       
   833     Initializes the contained widget.
       
   834 */
   564 void HsWidgetHost::action_initialize()
   835 void HsWidgetHost::action_initialize()
   565 {    
   836 {    
   566     mRootPathProperty.write(mWidget, mComponent->rootPath());
   837     mRootPathProperty.write(mWidget, mComponent->rootPath());
   567     setPreferencesToWidget();
   838     setPreferencesToWidget();
   568     setOnline(HsScene::instance()->isOnline());
   839     setOnline(HsScene::instance()->isOnline());
   569     mOnInitializeMethod.invoke(mWidget);
   840     mOnInitializeMethod.invoke(mWidget);
   570 }
   841 }
   571 
   842 
       
   843 /*!
       
   844     Uninitializes the contained widget.
       
   845 */
   572 void HsWidgetHost::action_uninitialize()
   846 void HsWidgetHost::action_uninitialize()
   573 {
   847 {
   574     mOnUninitializeMethod.invoke(mWidget);
   848     mOnUninitializeMethod.invoke(mWidget);
   575 }
   849 }
   576 
   850 
       
   851 /*!
       
   852     Puts the contained widget into show state.
       
   853 */
   577 void HsWidgetHost::action_show()
   854 void HsWidgetHost::action_show()
   578 {
   855 {
   579     if (!mIsFinishing) {
   856     if (!mIsFinishing) {
   580         mOnShowMethod.invoke(mWidget);
   857         mOnShowMethod.invoke(mWidget);
   581     }
   858     }
   582 }
   859 }
   583 
   860 
       
   861 /*!
       
   862     Puts the contained widget into hidden state.
       
   863 */
   584 void HsWidgetHost::action_hide()
   864 void HsWidgetHost::action_hide()
   585 {
   865 {
   586     if (!mIsFinishing) {
   866     if (!mIsFinishing) {
   587         mOnHideMethod.invoke(mWidget);
   867         mOnHideMethod.invoke(mWidget);
   588     }
   868     }
   589 }
   869 }
   590 
   870 
       
   871 /*!
       
   872     Notifies the home screen framework that this widget
       
   873     host has moved to finished state.
       
   874 */
   591 void HsWidgetHost::action_finished()
   875 void HsWidgetHost::action_finished()
   592 {
   876 {
   593     emit finished();
   877     emit finished();
   594 }
   878 }
   595 
   879 
       
   880 /*!
       
   881     Notifies the home screen framework that this widget
       
   882     host has moved to faulted state.
       
   883 */
   596 void HsWidgetHost::action_faulted()
   884 void HsWidgetHost::action_faulted()
   597 {
   885 {
   598     emit faulted();
   886     emit faulted();
   599 }
   887 }
   600 
   888 
       
   889 /*!
       
   890     Removes the contained widget from the home screen
       
   891     database.
       
   892 */
   601 void HsWidgetHost::action_remove()
   893 void HsWidgetHost::action_remove()
   602 {
   894 {
   603     HsDatabase *db = HsDatabase::instance();
   895     HsDatabase *db = HsDatabase::instance();
   604     
   896     
   605     db->deleteWidget(mDatabaseId);
   897     db->deleteWidget(mDatabaseId);
   606     mDatabaseId = -1;
   898     mDatabaseId = -1;
   607 }
   899 }
   608 
   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 */
   609 void HsWidgetHost::onFinished()
   916 void HsWidgetHost::onFinished()
   610 {
   917 {
   611     mIsFinishing = true;
   918     mIsFinishing = true;
   612     emit event_finished();
   919     emit event_finished();
   613 }
   920 }
   614  
   921  
       
   922 /*!
       
   923     Handles contained widget's error event.
       
   924     Moves this widget host to faulted state.
       
   925 */
   615 void HsWidgetHost::onError()
   926 void HsWidgetHost::onError()
   616 {
   927 {
   617     mIsFinishing = true;
   928     mIsFinishing = true;
   618     emit event_faulted();
   929     emit event_faulted();
   619 }
   930 }
   620 
   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 */
   621 void HsWidgetHost::onSetPreferences(const QStringList &names)
   937 void HsWidgetHost::onSetPreferences(const QStringList &names)
   622 {
   938 {
   623     if (names.isEmpty()) {
   939     if (names.isEmpty()) {
   624         return;
   940         return;
   625     }
   941     }