diff -r 000000000000 -r 16d8024aca5e src/hbcore/gui/hbdialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hbcore/gui/hbdialog.cpp Mon Apr 19 14:02:13 2010 +0300 @@ -0,0 +1,460 @@ +/**************************************************************************** +** +** 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 "hbdialog.h" +#include "hbdialog_p.h" +#include "hbinstance.h" +#include "hbaction.h" +#include "hbstyleoptionpopup.h" +#include "hbdeviceprofile.h" +#include "hbevent.h" +#include "hbtoolbar_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // krazy:exclude=qclasses + +#include + +#ifdef HB_EFFECTS +#include "hbeffectinternal_p.h" +#define HB_POPUP_ITEM_TYPE "HB_POPUP" +#endif + +/*! + @stable + @hbcore + \class HbDialog + \brief HbDialog is a base class for different popup notes in Hb library. + + \image html hbpopup.png A popup with a header widget, a list as a content widget, + and two action buttons. + + HbDialog is a concrete class. The content for a custom popup is implemented in + a separate widget, which is set to the popup with method setContentWidget(). + + Lastly shown popup is always positioned in Z order on the the top of already visible popups. + A popup can be permanent or automatically dismissed after a time-out. + Modal popups interrupt any other user interaction outside of the popup while they are visible, + whereas non-modal popups do not. + + An example of how to create a simple modal popup and show it. + \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,13} + + An example of how to create a non-modal popup and show it. + \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,26} +*/ + +/*! + \reimp + \fn int HbDialog::type() const + */ + +HbDialogPrivate::HbDialogPrivate( ) : + contentWidget(0), + headingWidget(0), + mainLayout(new QGraphicsLinearLayout(Qt::Vertical)), + primaryAction(0), + secondaryAction(0), + closingAction(0), + toolBar(0) +{ +} + +HbDialogPrivate::~HbDialogPrivate() +{ +} + +void HbDialogPrivate::init() +{ + Q_Q(HbDialog); + + // Content is responsible of adding spacings & margins + mainLayout->setSpacing(0); + mainLayout->setContentsMargins(0,0,0,0); + + q->setLayout(mainLayout); + mainLayout->setMinimumSize(0, 0); +} + +void HbDialogPrivate::setWidget(int layoutIndex, QGraphicsWidget *&destWidget, QGraphicsWidget *widget) +{ + Q_Q(HbDialog); + if (destWidget != widget) { + if (destWidget) { + mainLayout->removeItem(destWidget); + delete destWidget; + destWidget = 0; + } + if (widget) { + destWidget = widget; + destWidget->setParentItem(q); + mainLayout->insertItem(layoutIndex, widget); + mainLayout->setAlignment(widget, Qt::AlignCenter); + } + + doLayout(); + } +} + +/* + Relayouts the popup. If expandSize is true it the new calculated size of the popup + cannot be smaller than the current size. +*/ +void HbDialogPrivate::doLayout() +{ + Q_Q(HbDialog); + if(q->mainWindow() && contentWidget) + { + if ( q->mainWindow()->layoutDirection() != contentWidget->layoutDirection() ) { + contentWidget->setLayoutDirection(q->mainWindow()->layoutDirection()); + } + } + + if (q->mainWindow() && headingWidget) { + if (q->mainWindow()->layoutDirection() != headingWidget->layoutDirection()) { + headingWidget->setLayoutDirection(q->mainWindow()->layoutDirection()); + } + } + + q->updateGeometry(); +} + + +/*! +* Constructs a popup with given \a parent graphics item.\n +* Note: popups with \a parent set as 0 are behaving as real popups. +* This is actually the intended use. +* +* However in some situation could be useful to embedd a popup into a QGraphicsItem. +* In this case a non zero \a parent value must be passed. +* Popups with parent items behaving just like any other QGraphicsWidget. +* The following features are not supported (i.e. ignored) for popup with parents: +* +* - modality +* - timeout +* - unfadedItems +* - dismissPolicy +* - signal aboutToClose +*/ +HbDialog::HbDialog(QGraphicsItem *parent) : + HbPopup(*new HbDialogPrivate, parent) +{ + Q_D(HbDialog); + d->q_ptr = this; + d->init(); +} + +/*! + \internal + */ +HbDialog::HbDialog(HbDialogPrivate &dd, QGraphicsItem *parent) : + HbPopup(dd, parent) +{ + Q_D(HbDialog); + d->q_ptr = this; + d->init(); +} + +/*! +* Destroys the popup. +*/ +HbDialog::~HbDialog() +{ +} + +/*! +@beta +* It returns the widget which is being added to the heading area +* \sa setHeadingWidget() +*/ +QGraphicsWidget * HbDialog::headingWidget() const +{ + Q_D(const HbDialog); + return (d->headingWidget); +} + +/*! +@beta +* Adds \a widget to the heading area. Ownership of the widget is transferred +* to popup. If \a headingWidget is 0 the heading widget is removed. +* \sa headingWidget() +*/ +void HbDialog::setHeadingWidget(QGraphicsWidget *headingWidget) +{ + Q_D(HbDialog); + HbStyle::setItemName(headingWidget,"heading"); + d->setWidget(0, d->headingWidget, headingWidget); +} + +/*! +* Returns the content widget property of the popup. +* HbDialog only draws a bordered rect, the rest is drawn by the content widget. +* \sa setContentWidget() +*/ +QGraphicsWidget *HbDialog::contentWidget() const +{ + Q_D(const HbDialog); + return d->contentWidget; +} + +/*! +* Sets the content widget property of the popup. +* HbDialog only draws a bordered rect, the rest is drawn by the content widget. +* Ownership of the widget is transferred +* to popup. If \a contentWidget is 0 the content widget is removed. +* \sa contentWidget() +*/ +void HbDialog::setContentWidget(QGraphicsWidget *contentWidget) +{ + Q_D(HbDialog); + HbStyle::setItemName(contentWidget,"content"); + d->setWidget((d->headingWidget?1:0), d->contentWidget, contentWidget); +} + +/*! +* It returns the primary action added to the control area +* \sa setPrimaryAction() +*/ +HbAction* HbDialog::primaryAction() const +{ + Q_D(const HbDialog); + return d->primaryAction; +} + +/*! +* It adds the given action to the control area. +* It is added to the left side of the control area if the layout direction of the application +* is left-to-right and in the vice-versa if the layout direction of the application +* is right-to-left. +* \sa primaryAction() +*/ +void HbDialog::setPrimaryAction(HbAction *action) +{ + Q_D(HbDialog); + if (d->primaryAction && action != d->primaryAction) { + removeAction(d->primaryAction); + } + d->primaryAction = action; + QAction *before = 0; //krazy:exclude=qclasses + if (actions().count()) { + before = actions().first(); + } + insertAction(before, action); +} + +/*! +* It returns the secondary action added to the control area +* \sa setSecondaryAction() +*/ +HbAction* HbDialog::secondaryAction() const +{ + Q_D(const HbDialog); + return(d->secondaryAction); +} + +/*! +* It adds the given action to the control area. +* It is added to the right side of the control area if the layout direction of the application +* is left-to-right and in the vice-versa if the layout direction of the application +* is right-to-left. +* \sa secondaryAction() +*/ +void HbDialog::setSecondaryAction(HbAction *action) +{ + Q_D(HbDialog); + if (d->secondaryAction && action != d->secondaryAction) { + removeAction(d->secondaryAction); + } + d->secondaryAction = action; + addAction(action); +} + +/*! + \deprecated HbDialog::exec() + is deprecated. Please use HbDialog::open( QObject* receiver, const char* member ) instead. +* +* Executes the popup synchronously. +* Note: when popup is executed syncronously it is always modal. +*/ +HbAction* HbDialog::exec() +{ + Q_D(HbDialog); + + HbAction *action = 0; + QPointer guard = this; + HbPopup::exec(); + if (!guard.isNull()) { + action = d->closingAction; + d->closingAction = 0; + } + return action; +} + +/*! @alpha +* +* Shows the dialog as modal dialog returning immediately. + +* Connects finished(HbAction*) signal to the slot specified by \a receiver and +* \a member. The signal will be disconnected from the slot when the +* popup is closed. +* +* For non modal popups, use show(). +*/ + +void HbDialog::open( QObject* receiver, const char* member ) +{ + Q_D(HbDialog); + if ( receiver && member ) { + connect( this, SIGNAL(finished(HbAction*)), receiver, member ); + d->receiverToDisconnectOnClose = receiver; + d->memberToDisconnectOnClose = member; + } else { + d->receiverToDisconnectOnClose = 0; + d->memberToDisconnectOnClose.clear(); + } + HbPopup::open(); +} + +/*! +* \reimp +*/ +// +// Sets the focus to its content widget. +// +void HbDialog::focusInEvent(QFocusEvent *event) +{ + Q_UNUSED(event); + if(contentWidget()) { + contentWidget()->setFocus(); + } +} + +/*! + \reimp + */ +void HbDialog::closeEvent ( QCloseEvent * event ) +{ + Q_D(HbDialog); + + HbAction *closingAction = qobject_cast(sender()); + if (closingAction && actions().contains(closingAction)) { + d->closingAction = closingAction; + emit finished( d->closingAction ); + } else { + HbAction* nullAction(0); + emit finished( nullAction ); + } + + HbPopup::closeEvent(event); +} + +/*! + \reimp + */ +void HbDialog::changeEvent(QEvent *event) +{ + Q_D(HbDialog); + if (event->type() == QEvent::StyleChange || + event->type() == QEvent::LayoutDirectionChange) { + d->doLayout(); + } + + HbPopup::changeEvent(event); +} + +/*! + \reimp + */ +bool HbDialog::event(QEvent *event) +{ + Q_D(HbDialog); + event->accept(); + + if (event->type() == QEvent::ActionAdded) { + if (!d->toolBar) { + // TODO: HbToolBar private interface should make it possible to choose + // different graphics for tool buttons. + d->toolBar = new HbToolBar(); + HbStyle::setItemName(d->toolBar ,"controls"); + d->toolBar->setParentItem(this); + d->toolBar->setOrientation(Qt::Horizontal); + HbToolBarPrivate::d_ptr(d->toolBar)->mDialogToolBar = true; + // prevent stretching buttons, should the content be small + // but dialog size forcibly large + d->mainLayout->addStretch(); + d->mainLayout->addItem(d->toolBar); + } + QActionEvent *actionEvent = static_cast(event); + d->toolBar->insertAction (actionEvent->before(), actionEvent->action()); + if (!parentItem()) { // only for popup without parent + connect(actionEvent->action(), SIGNAL(triggered()), this, SLOT(close())); + } + d->doLayout(); + return true; + + } else if (event->type() == QEvent::ActionRemoved) { + + QActionEvent *actionEvent = static_cast(event); + // remove primary or secondary action if set + if (actionEvent->action() == d->primaryAction) { + d->primaryAction = 0; + } else if (actionEvent->action() == d->secondaryAction) { + d->secondaryAction = 0; + } + disconnect(actionEvent->action(), 0, this, 0); + + if (d->toolBar) { + d->toolBar->removeAction(actionEvent->action()); + if (!d->toolBar->actions().count()) { + d->mainLayout->removeItem(d->toolBar); + d->toolBar->deleteLater(); + d->toolBar = 0; + } + } + d->doLayout(); + return true; + + } else if (event->type() == HbEvent::LayoutRequest) { + if (d->toolBar + && mainWindow() + && d->toolBar->layoutDirection() != mainWindow()->layoutDirection() + && !d->toolBar->testAttribute(Qt::WA_SetLayoutDirection)) { + d->toolBar->setLayoutDirection(mainWindow()->layoutDirection()); + d->toolBar->setAttribute(Qt::WA_SetLayoutDirection, false); + } + d->doLayout(); + } + return HbPopup::event(event); +} + +#include "moc_hbdialog.cpp"