src/hbcore/gui/hbmenu.cpp
changeset 1 f7ac710697a9
parent 0 16d8024aca5e
child 2 06ff229162e9
equal deleted inserted replaced
0:16d8024aca5e 1:f7ac710697a9
    33 #ifdef HB_EFFECTS
    33 #ifdef HB_EFFECTS
    34 #include "hbeffect.h"
    34 #include "hbeffect.h"
    35 #include "hbeffectinternal_p.h"
    35 #include "hbeffectinternal_p.h"
    36 bool HbMenuPrivate::menuEffectsLoaded = false;
    36 bool HbMenuPrivate::menuEffectsLoaded = false;
    37 #endif
    37 #endif
       
    38 #include "hbglobal_p.h"
    38 
    39 
    39 #include <QPointer>
    40 #include <QPointer>
    40 
    41 
    41 Q_DECLARE_METATYPE (QAction*)// krazy:exclude=qclasses
    42 Q_DECLARE_METATYPE (QAction*)// krazy:exclude=qclasses
    42 
    43 
    67     subMenuAction = new HbAction(q);
    68     subMenuAction = new HbAction(q);
    68     subMenuAction->setMenu(q);
    69     subMenuAction->setMenu(q);
    69     q->setTimeout(HbPopup::ContextMenuTimeout);
    70     q->setTimeout(HbPopup::ContextMenuTimeout);
    70 
    71 
    71     q->setBackgroundFaded(false);
    72     q->setBackgroundFaded(false);
    72     q->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
    73 }
    73 }
    74 
    74 
    75 void HbMenuPrivate::addPopupEffects()
    75 void HbMenuPrivate::addPopupEffects()
    76 {
    76 {
    77 #ifdef HB_EFFECTS
    77 #ifdef HB_EFFECTS
   106         if (hasEffects) {
   106         if (hasEffects) {
   107             HbEffect::start(currentItem, "HB_menuitem", "clicked");
   107             HbEffect::start(currentItem, "HB_menuitem", "clicked");
   108         }
   108         }
   109 #endif
   109 #endif
   110         HbAction *hbAction = qobject_cast<HbAction *>(currentItem->action());
   110         HbAction *hbAction = qobject_cast<HbAction *>(currentItem->action());
   111         if (hbAction && hbAction->menu()) {
   111         if (hbAction && hbAction->menu() && !actionTriggered) {
   112             hbAction->trigger();
   112             hbAction->trigger();
   113             stopTimeout();
   113             stopTimeout();
   114             openSubmenu(currentItem);
   114             openSubmenu(currentItem);
   115         } else {
   115         } else {
   116             q->close();
   116             q->close();
   129 {
   129 {
   130     Q_Q(HbMenu);
   130     Q_Q(HbMenu);
   131     if (!menuItemView && q->actions().count()){
   131     if (!menuItemView && q->actions().count()){
   132         menuItemView = new HbMenuListView(q, q);
   132         menuItemView = new HbMenuListView(q, q);
   133         HbStyle::setItemName(menuItemView, "content");
   133         HbStyle::setItemName(menuItemView, "content");
   134         /* This is for qt versions 4.5,which had the clipping problem.
   134         //This optimises case of options menu which otherwise updates its primitives twice.
   135            FOR http://www.qtsoftware.com/developer/task-tracker/index_html?id=257232&method=entry
       
   136           see also HbMenu constructor */
       
   137 #if QT_VERSION < 0x040600
       
   138         menuItemView->setFlag( QGraphicsItem::ItemClipsChildrenToShape, false );
       
   139 #endif
       
   140    //This optimises case of options menu which otherwise updates its primitives twice.
       
   141         if (menuType ==  HbMenu::OptionsMenu)
   135         if (menuType ==  HbMenu::OptionsMenu)
   142             q->setFrameType(HbPopup::Strong);
   136             q->setFrameType(HbPopup::Strong);
   143     	else
   137     	else
   144             q->setFrameType(HbPopup::Weak);
   138             q->setFrameType(HbPopup::Weak);
   145         if (polished)//This check can be removed once base class repolish is fixed.
   139         if (polished)//This check can be removed once base class repolish is fixed.
   292         }
   286         }
   293         q->close();
   287         q->close();
   294     }
   288     }
   295 }
   289 }
   296 
   290 
       
   291 void HbMenuPrivate::_q_handleMenuAfterOrientationChange()
       
   292 {
       
   293     Q_Q(HbMenu);
       
   294     if ( menuType == HbMenu::ContextMenu || menuType == HbMenu::OptionsMenu ) {
       
   295         if(activeSubMenu){
       
   296             HbAction* action = activeSubMenu->activeAction();
       
   297             if(action) {
       
   298                 closeMenuRecursively(action);
       
   299             }
       
   300             closeSubmenu();
       
   301         }
       
   302         q->close();
       
   303     }
       
   304 }
       
   305 
       
   306 /*!
       
   307 * closes the menu after Orientation change
       
   308 */
       
   309 void HbMenuPrivate::closeMenuAfterOrientationChange()
       
   310 {
       
   311     Q_Q(HbMenu);
       
   312     HbMainWindow* w(q->mainWindow());
       
   313     if ( w ){
       
   314         QObject::disconnect( w, SIGNAL(aboutToChangeOrientation()),
       
   315                              q, SLOT(_q_handleMenuAfterOrientationChange()));
       
   316         QObject::connect( w, SIGNAL(aboutToChangeOrientation()),
       
   317                  q, SLOT(_q_handleMenuAfterOrientationChange()));
       
   318     }
       
   319 }
       
   320 
       
   321 void HbMenuPrivate::closeMenuRecursively(HbAction* menuAction)
       
   322 {
       
   323     if(menuAction->menu() && menuAction->menu()->activeAction()) {
       
   324         closeMenuRecursively(menuAction->menu()->activeAction());
       
   325     }
       
   326     if(menuAction->menu()) {
       
   327         menuAction->menu()->close();
       
   328     }
       
   329 }
       
   330 
       
   331 
   297 bool HbMenuPrivate::menuTimedOut(HbMenu* menu)
   332 bool HbMenuPrivate::menuTimedOut(HbMenu* menu)
   298 {
   333 {
   299     return (menu && menu->timeout() > 0 && HbMenuPrivate::d_ptr(menu)->timedOut);
   334     return (menu && menu->timeout() > 0 && HbMenuPrivate::d_ptr(menu)->timedOut);
   300 }
   335 }
   301 
   336 
   312     Q_Q(HbMenu);
   347     Q_Q(HbMenu);
   313     if (mSubMenuItem) {        
   348     if (mSubMenuItem) {        
   314         qreal upperEdge = mSubMenuItem->scenePos().y() + mSubMenuItem->size().height() * 2 / 3;
   349         qreal upperEdge = mSubMenuItem->scenePos().y() + mSubMenuItem->size().height() * 2 / 3;
   315         QSizeF windowSize = QSizeF(0,0);
   350         QSizeF windowSize = QSizeF(0,0);
   316         if (q->mainWindow()) {
   351         if (q->mainWindow()) {
   317             QGraphicsWidget *viewPortItem = q->mainWindow()->element(HbMainWindow::ViewportItem);
   352             windowSize = q->mainWindow()->layoutRect().size();
   318             if (viewPortItem) {
       
   319                 windowSize = viewPortItem->size();
       
   320             }
       
   321         }
   353         }
   322         if (windowSize.height() - mDownMargin - q->preferredHeight() < upperEdge) {
   354         if (windowSize.height() - mDownMargin - q->preferredHeight() < upperEdge) {
   323             upperEdge = windowSize.height() - mDownMargin - q->preferredHeight();
   355             upperEdge = windowSize.height() - mDownMargin - q->preferredHeight();
   324         }
   356         }
   325         if (q->layoutDirection() == Qt::LeftToRight) {
   357         if (q->layoutDirection() == Qt::LeftToRight) {
   341         }
   373         }
   342     }
   374     }
   343 }
   375 }
   344 
   376 
   345 /*!
   377 /*!
   346     @stable
   378     @beta
   347     @hbcore
   379     @hbcore
   348     \class HbMenu
   380     \class HbMenu
   349     \brief HbMenu is a menu widget for use in HbView.
   381     \brief HbMenu is a menu widget for use in HbView.
   350 
   382 
   351     \image html hbmenu.png A menu with checkable items and a sub-menu.
   383     \image html hbmenu.png A menu with checkable items and a sub-menu.
   444         HbPopup(*new HbMenuPrivate, parent)
   476         HbPopup(*new HbMenuPrivate, parent)
   445 {
   477 {
   446     Q_D(HbMenu);
   478     Q_D(HbMenu);
   447     d->q_ptr = this;
   479     d->q_ptr = this;
   448     d->init();
   480     d->init();
   449     /* This is for qt versions 4.5,which had the clipping problem.
   481     setModal(true);
   450            FOR http://www.qtsoftware.com/developer/task-tracker/index_html?id=257232&method=entry
       
   451            */
       
   452 #if QT_VERSION < 0x040600
       
   453     setFlag( QGraphicsItem::ItemClipsChildrenToShape, true );
       
   454 #endif
       
   455 }
   482 }
   456 
   483 
   457 /*!
   484 /*!
   458     Constructs a menu with \a title and \a parent graphics item.
   485     Constructs a menu with \a title and \a parent graphics item.
   459     \param title is the menu title.
   486     \param title is the menu title.
   490         }
   517         }
   491     }
   518     }
   492 }
   519 }
   493 
   520 
   494 /*!
   521 /*!
   495     \deprecated HbMenu::exec(HbAction*)
   522  \deprecated HbMenu::exec(HbAction*)
   496         is deprecated. Please use void HbMenu::open( QObject *receiver, const char *member )
   523          is deprecated. Please use
   497         or HbMenu::show() instead.
   524   void HbMenu::open( QObject *receiver, const char *member ) or 
       
   525   HbMenu::show() instead.
   498 
   526 
   499     Executes the menu synchronously so that given \a action
   527     Executes the menu synchronously so that given \a action
   500     is active.
   528     is active.
   501 
   529 
   502     \param action is the action that is active when the menu is shown.
   530     \param action is the action that is active when the menu is shown.
   517     of its sub-menus, or 0 if no item was triggered (normally because
   545     of its sub-menus, or 0 if no item was triggered (normally because
   518     the user closed or cancelled the menu).
   546     the user closed or cancelled the menu).
   519  */
   547  */
   520 HbAction *HbMenu::exec(HbAction *action)
   548 HbAction *HbMenu::exec(HbAction *action)
   521 {
   549 {
       
   550     HB_DEPRECATED("HbMenu::exec is deprecated. Use HbMenu::show() or HbMenu::open() instead!");
   522     Q_D(HbMenu);
   551     Q_D(HbMenu);
   523     if (actions().count() == 0) {
   552     if (actions().count() == 0) {
   524         return 0;
   553         return 0;
   525     }
   554     }
   526 
   555 
   546         return 0;
   575         return 0;
   547     }
   576     }
   548 }
   577 }
   549 
   578 
   550 /*!
   579 /*!
   551     \deprecated HbMenu::exec(const QPointF&, HbAction*)
   580   \deprecated HbMenu::exec(const QPointF&, HbAction*)
   552         is deprecated. Please use void HbMenu::open( QObject *receiver, const char *member )
   581      is deprecated. Please use
   553         or HbMenu::show() and setPreferredPos() instead.
   582   void HbMenu::open( QObject *receiver, const char *member ) or 
       
   583   HbMenu::show() and setPreferredPos() instead.
   554 
   584 
   555     Executes the menu synchronously at \a pos so that given \a action
   585     Executes the menu synchronously at \a pos so that given \a action
   556     is active.
   586     is active.
   557 
   587 
   558     \param pos is the position at which the menu is shown.
   588     \param pos is the position at which the menu is shown.
   691 HbAction *HbMenu::insertSeparator(HbAction *before)
   721 HbAction *HbMenu::insertSeparator(HbAction *before)
   692 {
   722 {
   693     HbAction *action = new HbAction(this);
   723     HbAction *action = new HbAction(this);
   694     action->setSeparator(true);
   724     action->setSeparator(true);
   695     action->setEnabled(false);
   725     action->setEnabled(false);
       
   726     action->setVisible(false);
   696     insertAction(before, action);
   727     insertAction(before, action);
   697     return action;
   728     return action;
   698 }
   729 }
   699 
   730 
   700 /*!
   731 /*!
   764  */
   795  */
   765 QVariant HbMenu::itemChange( GraphicsItemChange change, const QVariant & value )
   796 QVariant HbMenu::itemChange( GraphicsItemChange change, const QVariant & value )
   766 {
   797 {
   767     Q_D(HbMenu);
   798     Q_D(HbMenu);
   768 
   799 
       
   800     if (change == QGraphicsItem::ItemSceneHasChanged) {
       
   801         d->closeMenuAfterOrientationChange();
       
   802     }
   769     if (change == QGraphicsItem::ItemVisibleChange) {
   803     if (change == QGraphicsItem::ItemVisibleChange) {
   770         if (value.toBool() && d->delayMenuConstruction) {
   804         if (value.toBool() && d->delayMenuConstruction) {
   771             d->delayedLayout();
   805             d->delayedLayout();
   772         }
   806         }
   773         if (value.toBool()) {
   807         if (value.toBool()) {
   777         else if (!value.toBool() && !d->menuItemView){
   811         else if (!value.toBool() && !d->menuItemView){
   778             d->delayMenuConstruction = true;
   812             d->delayMenuConstruction = true;
   779         }
   813         }
   780     }
   814     }
   781     return HbPopup::itemChange(change,value);
   815     return HbPopup::itemChange(change,value);
   782 }
       
   783 
       
   784 /*!
       
   785     \reimp
       
   786  */
       
   787 void HbMenu::keyPressEvent(QKeyEvent *event)
       
   788 {
       
   789     //TODO: check if non-touch version works with the key bindings below
       
   790     Q_D(HbMenu);
       
   791     switch( event->key() ) {
       
   792             case Qt::Key_Up:
       
   793             case Qt::Key_Down:
       
   794         break;
       
   795             case Qt::Key_Right:
       
   796         layoutDirection() == Qt::LeftToRight
       
   797                 ? d->openSubmenu()
       
   798                     : d->closeSubmenu();
       
   799         break;
       
   800             case Qt::Key_Left:
       
   801         layoutDirection() == Qt::LeftToRight
       
   802                 ? d->closeSubmenu()
       
   803                     : d->openSubmenu();
       
   804         break;
       
   805             case Qt::Key_Backspace:
       
   806         d->closeSubmenu();
       
   807         break;
       
   808             case Qt::Key_Escape:
       
   809         close();
       
   810         break;
       
   811             default:
       
   812         HbPopup::keyPressEvent( event );
       
   813         break;
       
   814     }
       
   815 }
       
   816 
       
   817 /*!
       
   818     \reimp
       
   819  */
       
   820 void HbMenu::keyReleaseEvent(QKeyEvent *event)
       
   821 {
       
   822     //TODO do we need this method?
       
   823     QGraphicsWidget::keyReleaseEvent( event );
       
   824 }
   816 }
   825 
   817 
   826 /*!
   818 /*!
   827    \reimp
   819    \reimp
   828 */
   820 */
   844             d->actionChanged(actionEvent);
   836             d->actionChanged(actionEvent);
   845             return true;
   837             return true;
   846         }
   838         }
   847     }
   839     }
   848     if (event->type() == QEvent::LayoutRequest) {
   840     if (event->type() == QEvent::LayoutRequest) {
   849         resize(preferredSize());
       
   850         if(d->menuItemView)
   841         if(d->menuItemView)
   851             d->menuItemView->contentWidget()->adjustSize();
   842             d->menuItemView->contentWidget()->adjustSize();
       
   843     } else if (event->type() == QEvent::GraphicsSceneResize){
   852         if (d->mSubMenuItem)
   844         if (d->mSubMenuItem)
   853             d->setSubMenuPosition();
   845             d->setSubMenuPosition();
   854     }
   846     }
   855 
   847 
   856     return HbPopup::event(event);
   848     return HbPopup::event(event);
   879     }
   871     }
   880 }
   872 }
   881 
   873 
   882 QPainterPath HbMenu::shape() const
   874 QPainterPath HbMenu::shape() const
   883 {
   875 {
   884     QRectF sceneRect = mapRectToScene(boundingRect());
   876     QRectF sceneRect = mapRectToScene(QRectF(-0.5, -0.5, boundingRect().width() + 0.5, boundingRect().height() + 0.5));
   885     QRectF clipRect = sceneRect.intersected(geometry());
   877     QRectF clipRect = sceneRect.intersected(QRectF(pos().x() - 0.5, pos().y() - 0.5, size().width() + 0.5, size().height() + 0.5));
   886     QPainterPath path;    
   878 
       
   879     QPainterPath path;
   887     path.addRect(mapRectFromScene(clipRect));
   880     path.addRect(mapRectFromScene(clipRect));
   888     return path;
   881 
       
   882     return path.intersected(HbPopup::shape());
   889 }
   883 }
   890 
   884 
   891 /*!  @alpha
   885 /*!  @alpha
   892  *
   886  *
   893  * Opens the menu and returns immediately.
   887  * Opens the menu and returns immediately.