src/hbcore/gui/hbpopupmanager.cpp
changeset 34 ed14f46c0e55
parent 6 c3690ec91ef8
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
    37 #include "hbmenu_p.h"
    37 #include "hbmenu_p.h"
    38 
    38 
    39 #include <QGraphicsWidget>
    39 #include <QGraphicsWidget>
    40 #include <QGraphicsSceneMouseEvent>
    40 #include <QGraphicsSceneMouseEvent>
    41 #include <QGraphicsLayout>
    41 #include <QGraphicsLayout>
    42 #include <QDebug>
       
    43 #include <QEvent>
    42 #include <QEvent>
       
    43 
       
    44 extern const char* KPositionManagedByVKB;
    44 
    45 
    45 HbPopupLayoutSpacer::HbPopupLayoutSpacer( QGraphicsItem *parent )
    46 HbPopupLayoutSpacer::HbPopupLayoutSpacer( QGraphicsItem *parent )
    46 : HbWidgetBase( parent )
    47 : HbWidgetBase( parent )
    47 {
    48 {
    48 #if QT_VERSION >= 0x040600
       
    49     setFlag(QGraphicsItem::ItemHasNoContents, true);
    49     setFlag(QGraphicsItem::ItemHasNoContents, true);
    50 #endif
       
    51     setAcceptedMouseButtons(Qt::NoButton);
    50     setAcceptedMouseButtons(Qt::NoButton);
    52 }
    51 }
    53 
    52 
    54 QSizeF HbPopupLayoutSpacer::sizeHint(Qt::SizeHint which, const QSizeF &constraint ) const
    53 QSizeF HbPopupLayoutSpacer::sizeHint(Qt::SizeHint which, const QSizeF &constraint ) const
    55 {
    54 {
    59         return QSizeF( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
    58         return QSizeF( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
    60     }
    59     }
    61     return QSizeF(0.f,0.f);
    60     return QSizeF(0.f,0.f);
    62 }
    61 }
    63 
    62 
    64 /*
       
    65 \reimp
       
    66 */
       
    67 void HbPopupLayoutSpacer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
       
    68 {
       
    69     Q_UNUSED(option)
       
    70     Q_UNUSED(widget);
       
    71     Q_UNUSED(painter);
       
    72 }
       
    73 
       
    74 
       
    75 HbPopupLayoutProxy::HbPopupLayoutProxy( HbPopup *popup, QGraphicsItem *parent )
    63 HbPopupLayoutProxy::HbPopupLayoutProxy( HbPopup *popup, QGraphicsItem *parent )
    76 : HbWidgetBase(parent), mPopup(popup)
    64 : HbWidgetBase(parent), mPopup(popup)
    77 {
    65 {
    78 #if QT_VERSION >= 0x040600
       
    79     setFlag(QGraphicsItem::ItemHasNoContents, true);
    66     setFlag(QGraphicsItem::ItemHasNoContents, true);
    80 #endif
       
    81     setAcceptedMouseButtons(Qt::NoButton);
    67     setAcceptedMouseButtons(Qt::NoButton);
    82     popup->installEventFilter(this);
    68     popup->installEventFilter(this);
    83 }
    69 }
    84 
    70 
    85 QSizeF HbPopupLayoutProxy::sizeHint(Qt::SizeHint which, const QSizeF &constraint ) const
    71 QSizeF HbPopupLayoutProxy::sizeHint(Qt::SizeHint which, const QSizeF &constraint ) const
    90     return QSizeF(0, 0);
    76     return QSizeF(0, 0);
    91 }
    77 }
    92 
    78 
    93 void HbPopupLayoutProxy::setGeometry(const QRectF &rect)
    79 void HbPopupLayoutProxy::setGeometry(const QRectF &rect)
    94 {
    80 {
    95     if (!mPopup.isNull()) {
    81      if (!mPopup.isNull()) {
    96         const QSizeF popupPreferredSize = 
    82         const QSizeF popupPreferredSize = 
    97                 mPopup->effectiveSizeHint(Qt::PreferredSize);
    83                 mPopup->effectiveSizeHint(Qt::PreferredSize);
    98         const QSizeF usedSize( qMin(rect.width(),   popupPreferredSize.width() ),
    84         const QSizeF usedSize( qMin(rect.width(),   popupPreferredSize.width() ),
    99                                qMin( rect.height(), popupPreferredSize.height() ) );
    85                                qMin( rect.height(), popupPreferredSize.height() ) );
   100         QPointF usedPos(rect.left(), rect.top());
    86         QPointF usedPos(rect.left(), rect.top());
   135             case HbPopup::RightEdgeCenter:
   121             case HbPopup::RightEdgeCenter:
   136                 usedx = qMin(x-uw, pw-uw);
   122                 usedx = qMin(x-uw, pw-uw);
   137                 usedy = qMin(y-uh/2, ph-uh);
   123                 usedy = qMin(y-uh/2, ph-uh);
   138                 break;
   124                 break;
   139             case HbPopup::BottomEdgeCenter:
   125             case HbPopup::BottomEdgeCenter:
       
   126                 {
   140                 usedx = qMin(x-uw/2, pw-uw);
   127                 usedx = qMin(x-uw/2, pw-uw);
   141                 usedy = qMin(y-uh, ph-uh);
   128                 HbMenu *menu = qobject_cast<HbMenu*>(mPopup);
       
   129                 if(menu && ((y-uh) < 0)) {
       
   130                     usedy = qMin(y,ph-uh);
       
   131                 }
       
   132                 else {
       
   133                     usedy = qMin(y-uh, ph-uh);
       
   134                 }
       
   135                 }
   142                 break;
   136                 break;
   143             case HbPopup::LeftEdgeCenter:
   137             case HbPopup::LeftEdgeCenter:
   144                 usedx = qMin(x, pw-uw);
   138                 usedx = qMin(x, pw-uw);
   145                 usedy = qMin(y-uh/2, ph-uh);
   139                 usedy = qMin(y-uh/2, ph-uh);
   146                 break;
   140                 break;
   150                 break;
   144                 break;
   151             default:
   145             default:
   152                 //should not happen
   146                 //should not happen
   153                 break;
   147                 break;
   154             }
   148             }
       
   149 
   155             if ( usedx < screenMargin ) usedx = screenMargin;
   150             if ( usedx < screenMargin ) usedx = screenMargin;
   156             if ( usedy < screenMargin ) usedy = screenMargin;
   151             if ( usedy < screenMargin ) usedy = screenMargin;
   157 
       
   158             usedPos = QPointF(usedx, usedy);
   152             usedPos = QPointF(usedx, usedy);
       
   153         }
       
   154         if (mPopup->isFullScreen()) {
       
   155             mPopup->setMaximumSize(parentItem()->boundingRect().width(), parentItem()->boundingRect().height());
       
   156             mPopup->setGeometry(0, 0, parentItem()->boundingRect().width(), parentItem()->boundingRect().height());
       
   157             ((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting = true;
       
   158             return;
   159         }
   159         }
   160         if (((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting) {
   160         if (((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting) {
   161             mPopup->setGeometry(QRectF(usedPos, usedSize));
   161             mPopup->setGeometry(QRectF(usedPos, usedSize));
       
   162             ((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting = true;            
       
   163         } else if (mPopup->property(KPositionManagedByVKB).isValid() &&
       
   164                    mPopup->property(KPositionManagedByVKB).toBool()) {
       
   165             //Special case for the popups which y-position is handled by VKB
       
   166             QPointF currentPos = mPopup->pos();
       
   167             currentPos.setX(usedPos.x());
       
   168             bool previousLayouting = ((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting;
   162             ((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting = true;
   169             ((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting = true;
       
   170             mPopup->setGeometry(QRectF(currentPos, usedSize));
       
   171             ((HbPopupPrivate*)HbPopupPrivate::d_ptr(mPopup))->mAutoLayouting = previousLayouting;
   163         } else {
   172         } else {
   164             mPopup->resize(usedSize);
   173             mPopup->resize(usedSize);
   165         }
   174         }
   166     }
   175     }
   167 }
   176 }
   181 bool HbPopupLayoutProxy::eventFilter(QObject *obj, QEvent *event)
   190 bool HbPopupLayoutProxy::eventFilter(QObject *obj, QEvent *event)
   182 {
   191 {
   183     Q_UNUSED( obj );
   192     Q_UNUSED( obj );
   184     switch( event->type() ) {
   193     switch( event->type() ) {
   185         case QEvent::LayoutRequest:
   194         case QEvent::LayoutRequest:
   186         case QEvent::ContextMenu:
   195         {
       
   196             activateParentLayout();
       
   197         } //fallthrough
   187         case QEvent::Close:
   198         case QEvent::Close:
   188             {
   199             {
   189             updateGeometry();
   200             updateGeometry();
   190             break;
   201             break;
   191             }
   202             }
   193             break;
   204             break;
   194     }
   205     }
   195     return false;
   206     return false;
   196 }
   207 }
   197 
   208 
   198 
   209 void HbPopupLayoutProxy::activateParentLayout()
   199 /*
   210 {
   200 \reimp
   211     if ( mPopup && parentLayoutItem() && parentLayoutItem()->isLayout()
   201 */
   212         && !static_cast<QGraphicsLayout*>(parentLayoutItem())->isActivated()) {
   202 void HbPopupLayoutProxy::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
   213         static_cast<QGraphicsLayout*>(parentLayoutItem())->activate();
   203 {
   214     }
   204     Q_UNUSED(option);
       
   205     Q_UNUSED(widget);
       
   206     Q_UNUSED(painter);
       
   207 }
   215 }
   208 
   216 
   209 HbPopupLayoutManager::HbPopupLayoutManager( HbPopup *popup, QGraphicsScene *scene ) 
   217 HbPopupLayoutManager::HbPopupLayoutManager( HbPopup *popup, QGraphicsScene *scene ) 
   210 : HbWidget()
   218 : HbWidget()
   211 {        
   219 {        
   212 #if QT_VERSION >= 0x040600
       
   213     setFlag(QGraphicsItem::ItemHasNoContents, true);
   220     setFlag(QGraphicsItem::ItemHasNoContents, true);
   214 #endif
       
   215     setAcceptedMouseButtons(Qt::NoButton);
   221     setAcceptedMouseButtons(Qt::NoButton);
   216     scene->addItem( this );
   222     scene->addItem( this );
       
   223     //adjust the size of popuplayoutmanager to its preferredSize
       
   224     //since it defines the geometries of popups.
       
   225     adjustSize();
   217 
   226 
   218     // create proxy
   227     // create proxy
   219     HbPopupLayoutProxy *childItem = new HbPopupLayoutProxy( popup, this );
   228     HbPopupLayoutProxy *childItem = new HbPopupLayoutProxy( popup, this );
   220 
   229 
   221     // create spacers
   230     // create spacers
   233             HbStyle::setItemName( childItem, "menu" );
   242             HbStyle::setItemName( childItem, "menu" );
   234         }
   243         }
   235     } else if ( metaObject->className() == QLatin1String("HbToolBarExtension" ) ) {
   244     } else if ( metaObject->className() == QLatin1String("HbToolBarExtension" ) ) {
   236         HbStyle::setItemName( childItem, "toolbar-extension" );
   245         HbStyle::setItemName( childItem, "toolbar-extension" );
   237     } else {
   246     } else {
   238         HbStyle::setItemName( childItem, "popup" );        
   247         HbStyle::setItemName( childItem, "popup" );
   239     }
   248     }
   240     setZValue(popup->zValue() - 1);
   249     setZValue(popup->zValue() - 1);
   241     if ( metaObject->className() == QLatin1String("HbVolumeSliderPopup") ) {
   250     if ( metaObject->className() == QLatin1String("HbVolumeSliderPopup") ) {
   242         HbStyle::setItemName( childItem, "volumesliderpopup" );
   251         HbStyle::setItemName( childItem, "volumesliderpopup" );
   243         connect(scene,SIGNAL(sceneRectChanged(QRectF)),this,SLOT(orientationChanged(QRectF)));
   252         connect(scene,SIGNAL(sceneRectChanged(QRectF)),this,SLOT(orientationChanged(QRectF)));
   268 \reimp
   277 \reimp
   269 */
   278 */
   270 void HbPopupLayoutManager::changeEvent(QEvent *event)
   279 void HbPopupLayoutManager::changeEvent(QEvent *event)
   271 {
   280 {
   272     HbWidget::changeEvent(event);
   281     HbWidget::changeEvent(event);
   273     if (event && event->type() == QEvent::LayoutDirectionChange) {
   282     if (event->type() == QEvent::LayoutDirectionChange) {
   274         repolish();
   283         repolish();
   275     }
   284     }
   276 
   285 
   277 }
       
   278 
       
   279 /*
       
   280 \reimp
       
   281 */
       
   282 void HbPopupLayoutManager::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
       
   283 {
       
   284     Q_UNUSED(option)
       
   285     Q_UNUSED(widget);
       
   286     Q_UNUSED(painter);
       
   287 }
   286 }
   288 
   287 
   289 
   288 
   290 /*
   289 /*
   291     \class HbPopupManagerPrivate
   290     \class HbPopupManagerPrivate
   309     Deliver mouseEvent to all HbPopupBackGround object for non-modal popups until event blocking
   308     Deliver mouseEvent to all HbPopupBackGround object for non-modal popups until event blocking
   310     item is found.
   309     item is found.
   311 */
   310 */
   312 void HbPopupManagerPrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
   311 void HbPopupManagerPrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
   313 {
   312 {
   314     foreach (QGraphicsItem *item, scene->items(mouseEvent->scenePos())) {
   313     //This function can be removed since popup background is handling the events
       
   314     Q_UNUSED(mouseEvent);
       
   315     /*foreach (QGraphicsItem *item, scene->items(mouseEvent->scenePos())) {
   315         if (eventBlockItem(item)) {
   316         if (eventBlockItem(item)) {
   316             break;
   317             break;
   317         }
   318         }
   318         if (item->type() == HbPrivate::ItemType_PopupBackGround) {
   319         if (item->type() == HbPrivate::ItemType_PopupBackGround) {
   319             static_cast<GraphicsItem *>(item)->sceneEvent(mouseEvent);
   320             static_cast<GraphicsItem *>(item)->sceneEvent(mouseEvent);
   320             // Finish loop if popup of background is modal
   321             // Finish loop if popup of background is modal
   321             if (static_cast<HbPopupBackGround *>(item)->isModal()) {
   322             if (static_cast<HbPopupBackGround *>(item)->isModal()) {
   322                 break;
   323                 break;
   323             }
   324             }
   324         }
   325         }
   325     }
   326     }*/
   326 }
   327 }
   327 
   328 
   328 /*
   329 /*
   329   Returns true if item is an event blocking item.
   330   Returns true if item is an event blocking item.
   330 */
   331 */
   377     popupCountRegisters[priority] = popupCountRegister;
   378     popupCountRegisters[priority] = popupCountRegister;
   378 }
   379 }
   379 
   380 
   380 void HbPopupManagerPrivate::eventHook(QEvent *event)
   381 void HbPopupManagerPrivate::eventHook(QEvent *event)
   381 {
   382 {
   382     if (event && event->type() == QEvent::GraphicsSceneMouseRelease && popupList.count() && scene) {
   383     Q_UNUSED(event);
       
   384     //This function can be removed since popup background is handling the events
       
   385    /* if (event && event->type() == QEvent::GraphicsSceneMouseRelease && popupList.count() && scene) {
   383         mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
   386         mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
   384     }
   387     }*/
   385 }
   388 }
   386 
   389 
   387 void HbPopupManagerPrivate::showPopup(HbPopup *popup)
   390 void HbPopupManagerPrivate::showPopup(HbPopup *popup)
   388 {
   391 {
   389     if (popup) {
   392     if (popup) {
   418                  popup->metaObject()->className() != QLatin1String("HbCharPreviewPane") &&
   421                  popup->metaObject()->className() != QLatin1String("HbCharPreviewPane") &&
   419                  popup->metaObject()->className() != QLatin1String("HbCandidateList") &&
   422                  popup->metaObject()->className() != QLatin1String("HbCandidateList") &&
   420                  popup->metaObject()->className() != QLatin1String("HbExactWordPopup") &&
   423                  popup->metaObject()->className() != QLatin1String("HbExactWordPopup") &&
   421                  popup->metaObject()->className() != QLatin1String("HbInputSmileyPicker") &&
   424                  popup->metaObject()->className() != QLatin1String("HbInputSmileyPicker") &&
   422                  popup->metaObject()->className() != QLatin1String("Hb12KeyCustomKeypad") &&
   425                  popup->metaObject()->className() != QLatin1String("Hb12KeyCustomKeypad") &&
   423 				 !popup->inherits("HbInputVkbWidget")) {
   426                  !popup->inherits("HbInputVkbWidget")) {
   424                 setGeometryForPopup( popup );
   427                 setGeometryForPopup( popup );
   425             }
   428             }
   426         }
   429         }
   427 
   430 
   428         // Check if popup is top level popup
   431         // Check if popup is top level popup
   451 {
   454 {
   452     //delete the layoutproxy and remove the popup from parentItems list
   455     //delete the layoutproxy and remove the popup from parentItems list
   453     //only if its in its destruction
   456     //only if its in its destruction
   454     bool popupInDestruction = (HbPopupPrivate::d_ptr(popup))->inDestruction;
   457     bool popupInDestruction = (HbPopupPrivate::d_ptr(popup))->inDestruction;
   455     if ( parentItems.contains( popup ) && (popupInDestruction)) {
   458     if ( parentItems.contains( popup ) && (popupInDestruction)) {
   456         //HbPopupLayoutManager *parentItem = parentItems[popup];        
   459         HbPopupLayoutManager *parentItem = parentItems[popup];
   457         parentItems.remove( popup );
   460         parentItems.remove( popup );
   458         //delete parentItem;
   461         delete parentItem;
   459     }
   462     }
   460 
   463 
   461     // Only execute if close if popup was in popupList before
   464     // Only execute if close if popup was in popupList before
   462     if (popupList.removeOne(popup)) {
   465     if (popupList.removeOne(popup)) {
   463         // Update popup count registers
   466         // Update popup count registers
   464         updateHash(HbPopupPrivate::d_ptr(popup)->priority(), popup->zValue());
   467         updateHash(HbPopupPrivate::d_ptr(popup)->priority(), popup->zValue());
   465 
   468 
   466         // Update fading
   469         // Update fading
   467         updateFading(true);
   470         updateFading();
   468 
   471 
   469         // Find new top level popup
   472         // Find new top level popup
   470         if (topLevelFocusablePopup && topLevelFocusablePopup == popup) {
   473         if (topLevelFocusablePopup && topLevelFocusablePopup == popup) {
   471             topLevelFocusablePopup = 0;
   474             topLevelFocusablePopup = 0;
   472             foreach (HbPopup *popup, popupList) {
   475             foreach (HbPopup *popup, popupList) {
   478         }
   481         }
   479 
   482 
   480         bool wasActivePopup = true;
   483         bool wasActivePopup = true;
   481         // If the previous popup was an inactive panel, then it would not have
   484         // If the previous popup was an inactive panel, then it would not have
   482         // gained focused. So no need to set the focus to the next topmost popup.
   485         // gained focused. So no need to set the focus to the next topmost popup.
   483         if (popup->isPanel() && !popup->isActive()) {
   486         if (popup->isPanel() && !HbPopupPrivate::d_ptr(popup)->mActivePopup) {
   484             wasActivePopup = false;
   487             wasActivePopup = false;
   485         }
   488         }
   486         if (topLevelFocusablePopup && wasActivePopup ) {
   489         if (topLevelFocusablePopup && wasActivePopup ) {
   487             topLevelFocusablePopup->setFocus();
   490             topLevelFocusablePopup->setFocus();
       
   491             if (HbPopupPrivate::d_ptr(topLevelFocusablePopup)->mActivePopup)
       
   492                 topLevelFocusablePopup->setActive(true);
   488         }
   493         }
   489         //TODO: this is not very efficient way of deciding if has already been deleted or not
   494         //TODO: this is not very efficient way of deciding if has already been deleted or not
   490         else if (initialFocusedItem && scene &&
   495         else if (initialFocusedItem && scene &&
   491                  scene->items().contains(initialFocusedItem)) {
   496                  scene->items().contains(initialFocusedItem)) {
   492 
   497 
   533         }
   538         }
   534 
   539 
   535         if (topFadingPopup) {
   540         if (topFadingPopup) {
   536             HbMainWindowPrivate::d_ptr(mainWindow)->fadeScreen(
   541             HbMainWindowPrivate::d_ptr(mainWindow)->fadeScreen(
   537                     HbPopupPrivate::d_ptr(topFadingPopup)->backgroundItem->zValue() - HbPrivate::FadingItemZValueUnit );
   542                     HbPopupPrivate::d_ptr(topFadingPopup)->backgroundItem->zValue() - HbPrivate::FadingItemZValueUnit );
       
   543         } else {
       
   544             HbMainWindowPrivate::d_ptr(mainWindow)->unfadeScreen();
   538         }
   545         }
   539     }
   546     }
   540 }
   547 }
   541 
   548 
   542 // Device wide fading change is requested
   549 // Device wide fading change is requested
   591 // no need to delete d because it is child of this object
   598 // no need to delete d because it is child of this object
   592 }
   599 }
   593 
   600 
   594 void HbPopupManager::eventHook(QEvent *event)
   601 void HbPopupManager::eventHook(QEvent *event)
   595 {
   602 {
   596     d->eventHook(event);
   603     //This function can be removed
       
   604     Q_UNUSED(event);
       
   605     //d->eventHook(event);
   597 }
   606 }
   598 
   607 
   599 void HbPopupManager::showPopup(HbPopup *popup)
   608 void HbPopupManager::showPopup(HbPopup *popup)
   600 {
   609 {
   601     d->showPopup(popup);
   610     d->showPopup(popup);