src/hbcore/gui/hbtoolbar.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 06 Jul 2010 14:36:53 +0300
changeset 7 923ff622b8b9
parent 6 c3690ec91ef8
child 21 4633027730f5
child 34 ed14f46c0e55
permissions -rw-r--r--
Revision: 201025 Kit: 2010127

/****************************************************************************
**
** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (developer.feedback@nokia.com)
**
** This file is part of the HbCore module of the UI Extensions for Mobile.
**
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at developer.feedback@nokia.com.
**
****************************************************************************/

#include "hbtoolbar.h"
#include "hbtoolbar_p.h"
#include "hbaction.h"
#include "hbtoolbutton.h"
#include "hbtoolbutton_p.h"
#include "hbapplication.h"
#include "hbnamespace_p.h"
#include "hbtoolbarextension.h"
#include "hbtoolbarextension_p.h"
#include "hbwidget_p.h"
#include "hbinstance.h"
#include "hbactionmanager_p.h"
#include "hbmainwindow_p.h"
#include "hbcolorscheme.h"

#include <hbwidgetfeedback.h>

#include <QGraphicsLinearLayout>
#include <QGraphicsSceneResizeEvent>
#include <QWidget> // for QWIDGETSIZE_MAX
#include <QActionEvent>
#include <QDebug>
#include <QGesture>

#ifdef HB_EFFECTS
#include "hbeffectinternal_p.h"
#endif

/*!
    @beta
    @hbcore
    \class HbToolBar
    \brief HbToolBar is a toolbar decorator.

    The HbToolBar class represents an HbView toolbar. It provides the
    interface for adding actions to the toolbar.

    Toolbar actions are added using one of the addAction() methods.
    Calling addAction() adds an HbToolButton to the toolbar and
    triggers the action when the button is pressed. The image and text
    specified with the action are applied to the toolbar button.

    HbToolBar also provides methods for adding pop-up toolbar
    extensions, represented by HbToolBarExtension objects.

    Example usage:
    \dontinclude ultimatecodesnippet/ultimatecodesnippet.cpp
    \skip Start of snippet 1
    \until End of snippet 1

    Note: calling hide() or setVisible(bool) on toolbar is not
    recommended.  Instead, use \a HbView::setItemVisible(), as in 
    this example:
    \dontinclude ultimatecodesnippet/ultimatecodesnippet.cpp
    \skip Start of snippet 59
    \until End of snippet 59

   
*/

/*!
    \reimp
    \fn int HbToolBar::type() const
 */

/*!
    \fn void HbToolBar::addAction(QAction *action)
    Adds a new action to the toolbar. It's appended to the end
    of the toolbar. Toolbar doesn't take ownership of the QAction.
  */

// ======== MEMBER FUNCTIONS ========

/*!
    Constructs a tool bar with \a parent.
*/

HbToolBar::HbToolBar( QGraphicsItem *parent )
    : HbWidget(*new HbToolBarPrivate, parent)
{
    Q_D(HbToolBar);
    d->q_ptr = this;
    d->init();
    setFlag(QGraphicsItem::ItemIsPanel);

}

/*!
    Protected constructor.
*/
HbToolBar::HbToolBar( HbToolBarPrivate &dd, QGraphicsItem *parent )
    : HbWidget(dd, parent)
{
    Q_D(HbToolBar);
    d->q_ptr = this;
    d->init();
}

/*!
    Destructor
 */
HbToolBar::~HbToolBar()
{    
    if (!scene() || !scene()->property("destructed").isValid()) {
        foreach (QAction *action, actions()) {// krazy:exclude=qclasses
            HbAction* hbAction = qobject_cast<HbAction *>(action);
            if (hbAction){
                if (hbAction->toolBarExtension()){
                    hbAction->toolBarExtension()->deleteLater();
                }
                hbAction->setToolBarExtension(0);
            }
        }
    }
}

/*!
    \overload

    Creates a new action with the given \a text. This action is added to
    the end of the toolbar. Toolbar retains ownership of the action.
*/
HbAction *HbToolBar::addAction( const QString &text )
{
    HbAction *action = new HbAction(text, this);
    addAction(action);
    return action;
}

/*!
    \overload

    Creates a new action with the given \a icon and \a text. This
    action is added to the end of the toolbar. Toolbar retains ownership of the action.
*/
HbAction *HbToolBar::addAction( const HbIcon &icon, const QString &text )
{
    HbAction *action = new HbAction(icon, text, this);
    addAction(action);
    return action;
}

/*!
    \overload

    Creates a new action with the given \a text. This action is added to
    the end of the toolbar. The action's \link HbAction::triggered()
    triggered()\endlink signal is connected to \a member in \a
    receiver. Toolbar retains ownership of the action.
*/
HbAction *HbToolBar::addAction( const QString &text, const QObject *receiver, const char *member )
{
    HbAction *action = new HbAction(text, this);
    QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
    addAction(action);
    return action;
}

/*!
    \overload

    Creates a new action with the icon \a icon and text \a text. This
    action is added to the end of the toolbar. The action's \link
    HbAction::triggered() triggered()\endlink signal is connected to \a
    member in \a receiver. Toolbar retains ownership of the action.
*/
HbAction *HbToolBar::addAction( const HbIcon &icon, const QString &text, const QObject *receiver, const char *member )
{
    HbAction *action = new HbAction(icon, text, this);
    QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
    addAction(action);
    return action;
}

/*!
    This convenience function adds the \a extension as an extension popup
    to the toolbar. Returns the HbAction triggering the \a extension.
*/
HbAction *HbToolBar::addExtension( HbToolBarExtension *extension )
{
    return insertExtension(0, extension);
}

/*!
    This convenience function inserts the \a extension as an extension popup
    before the action \a before.

    It appends the action if \a before is 0 or \a before is not a valid
    action for this widget.

    Returns the HbAction triggering the \a extension.
*/
HbAction *HbToolBar::insertExtension( HbAction *before, HbToolBarExtension *extension )
{    
    Q_D(HbToolBar);

    d->initToolBarExtension(extension);

    insertAction(before, extension->extensionAction());
    return extension->extensionAction();
}

/*! @beta
    \brief  Returns the orientation of the tool bar.

    \sa setOrientation
 */
Qt::Orientation HbToolBar::orientation() const
{
    Q_D(const HbToolBar);
    return d->mOrientation;
}

/*! @beta
    Sets the \a orientation of the tool bar.

    \sa orientation
 */
void HbToolBar::setOrientation( Qt::Orientation orientation )
{
    Q_D(HbToolBar);

    d->setOrientation ( orientation );
    d->minimumToolButtonSize = QSizeF();
}

/*!
    Emits areaChanged() whenever the tool bar's visibility or position changes.
*/
QVariant HbToolBar::itemChange( GraphicsItemChange change, const QVariant &value )
{
    Q_D(HbToolBar);
    QVariant result = HbWidget::itemChange(change, value);

    switch (change) {
    case ItemVisibleHasChanged:
        if (d->emitVisibilityChangeSignal && value.toBool()) {
            QMetaObject::invokeMethod(&d->core, "visibilityChanged", Qt::DirectConnection);
            d->emitVisibilityChangeSignal = false;
        }
        break;
    case ItemVisibleChange:
        if (d->mOrientationEffectsRunning)
            return result;
        if (value.toBool()) {
            if (d->mDoLayout && d->mDoLayoutPending) {
                d->doLayout();
            }
            if (!d->mDialogToolBar) {
                d->doLazyInit();
                d->delayedStartEffects = d->mDoLayoutPending && !d->mSuppressNextAppearEffect;
                if (!d->delayedStartEffects && d->hasEffects && !d->mSuppressNextAppearEffect) {
                    d->startAppearEffect();
                }
                d->mSuppressNextAppearEffect = false;
                d->delayedHide = d->hasEffects;
            }
        } else {
            if(d->moreExtension && d->moreExtension->isVisible()){
               d->moreExtension->setVisible(false);
            }
            bool hideDelayed = d->delayedHide;
            if (d->delayedHide && d->hasEffects) { // about to hide and we wanna delay hiding
                // This check solves the situation where toolbar is hidden by its parent.
                // Delayed hide changes explicit bit in qgraphicsitem which makes
                // toolbar to stay hidden when parent becomes visible again.
                // There is a small misbehaviour when parentItem is hidden and hide was explicitely
                // called for toolbar. In this case toolbar hides without the effect.
                if ((!parentItem() || (parentItem() && parentItem()->isVisible()))) {
                    if (!d->hidingInProgress) { // Prevent reentrance
                        d->hidingInProgress = true;
                        d->startDisappearEffect();
                        d->delayedHide = false;
                    }
                } else {
                    d->delayedHide = false;
                }
            }
            if (hideDelayed) {
                return true;
            } else {
                d->delayedHide = d->hasEffects;
                d->hidingInProgress = false;
#ifdef HB_EFFECTS
                HbEffect::cancel(this, QString(), true);
#endif
            }
            if (d->mVisibleToolButtons.count()){
                d->emitVisibilityChangeSignal = true;
                QMetaObject::invokeMethod(&d->core, "visibilityChanged", Qt::QueuedConnection);
            }
        }
    break;
        default:
            break;
    }
    return result;
}

/*!
    Reimplemented from QGraphicsWidget::changeEvent().
 */
void HbToolBar::changeEvent( QEvent *event )
{
    Q_D(HbToolBar);
    if (event->type() == QEvent::LayoutDirectionChange) {
        d->updateToolBarExtensions();
        d->updateButtonsLayoutDirection();
    }

    QGraphicsWidget::changeEvent(event);
}

/*!
    Reimplemented from QGraphicsWidget::resizeEvent().
 */
void HbToolBar::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    Q_D(HbToolBar);
    HbWidget::resizeEvent(event);
    if (isVisible() && d->mDoLayout) {
        d->updateToolBarForSizeChange();
    }
}

/*!
    \reimp
 */
void HbToolBar::hideEvent(QHideEvent *event)
{
    HbWidget::hideEvent(event);
}

/*!
  \reimp
  */
/*!
    \reimp
 */
bool HbToolBar::event(QEvent *event)
{
    Q_D(HbToolBar);   
    switch( event->type() ) {        
    case QEvent::ActionAdded:
        d->actionAdded(static_cast<QActionEvent*>(event));
        return true;
    case QEvent::ActionRemoved:
        d->actionRemoved(static_cast<QActionEvent*>(event));
        return true;
    case QEvent::ActionChanged:
        // happens at least when action->setVisible(bool visible) is called
        if (d->polished && isVisible()) {
            d->resetVisibleButtonsList();
            d->doLayout();
        } else {
            d->mDoLayoutPending = true;
        }
        return true;
        default:
            return HbWidget::event(event);
    }    
}

/*!
    \reimp
 */
void HbToolBar::gestureEvent(QGestureEvent *)
{

}

void HbToolBar::updatePrimitives()
{
    Q_D(HbToolBar);
    for (int i = 0; i < d->mVisibleToolButtons.count(); i++) {
        d->mVisibleToolButtons.at(i)->updatePrimitives();
    }
    if (d->moreExtensionButton) {
        d->moreExtensionButton->updatePrimitives();
    }
}

/*!
  \reimp
  */
void HbToolBar::polish(HbStyleParameters &params)
{
    Q_D(HbToolBar);
    HbWidget::polish(params);
    if (d->mDoLayoutPending) {
        d->doLayout();
    }
}

#include "moc_hbtoolbar.cpp"