src/hbwidgets/devicedialogs/hbdevicemessagebox.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbWidgets module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include <hbdevicedialog.h>
       
    27 #include <hbaction.h>
       
    28 #include <hbdevicedialogtrace_p.h>
       
    29 #include "hbdevicemessagebox.h"
       
    30 #include "hbdevicemessagebox_p.h"
       
    31 
       
    32 #include <QTimer>
       
    33 #include <QTimerEvent>
       
    34 #include <QAction>
       
    35 #include <QPointer>
       
    36 
       
    37 HbDeviceMessageBoxPrivate::HbDeviceMessageBoxPrivate() : QObject(),
       
    38     mDeviceDialog(0),
       
    39     mVisible(false),
       
    40     mUpdateTimerId(0)
       
    41 {
       
    42     TRACE_ENTRY
       
    43     for(int i = 0; i < NumActions; i++) {
       
    44         mDefaultActions[i] = 0;
       
    45     }
       
    46     TRACE_EXIT
       
    47 }
       
    48 
       
    49 HbDeviceMessageBoxPrivate::~HbDeviceMessageBoxPrivate()
       
    50 {
       
    51     TRACE_ENTRY
       
    52     // information/warning dialogs may be left at server when client is deleted. If there are no connected
       
    53     // signals, device dialog widget is not deleted but runs at server and is closed by a timeout.
       
    54     if (mProperties[Type].mValue.toInt() != HbMessageBox::MessageTypeQuestion &&
       
    55         q_ptr->receivers(SIGNAL(aboutToClose())) <= 0) {
       
    56         mDeviceDialog->disconnect(q_ptr, SLOT(aboutToClose()));
       
    57         mDeviceDialog->disconnect(this, SLOT(triggerAction(QVariantMap)));
       
    58         if (mUpdateTimerId != 0) {
       
    59             // There's a pending update
       
    60             sendToServer(false); // this also kills the timer
       
    61         }
       
    62     }
       
    63     delete mDeviceDialog;
       
    64     for(int i = 0; i < NumActions; i++) {
       
    65         delete mDefaultActions[i];
       
    66     }
       
    67     TRACE_EXIT
       
    68 }
       
    69 
       
    70 void HbDeviceMessageBoxPrivate::init()
       
    71 {
       
    72     TRACE_ENTRY
       
    73 
       
    74     initProperties();
       
    75 
       
    76     mDeviceDialog = new HbDeviceDialog;
       
    77     connect(mDeviceDialog, SIGNAL(deviceDialogClosed()), q_ptr, SIGNAL(aboutToClose()));
       
    78     connect(mDeviceDialog, SIGNAL(dataReceived(QVariantMap)), this, SLOT(triggerAction(QVariantMap)));
       
    79 
       
    80     TRACE_EXIT
       
    81 }
       
    82 
       
    83 void HbDeviceMessageBoxPrivate::initProperties()
       
    84 {
       
    85     for(int i = 0; i < NumProperties; i++) {
       
    86         mProperties[i].mFlags = NoFlags;
       
    87     }
       
    88     clearActions();
       
    89 
       
    90     QString text;
       
    91     q_ptr->setText(text);
       
    92     q_ptr->setIconName(text);
       
    93     q_ptr->setIconAlignment(Qt::AlignCenter);
       
    94     q_ptr->setIconVisible(true);
       
    95     q_ptr->setAnimationDefinition(text);
       
    96 
       
    97     switch(mProperties[Type].mValue.toInt()) {
       
    98     case HbMessageBox::MessageTypeInformation:
       
    99     case HbMessageBox::MessageTypeWarning:
       
   100         q_ptr->setDismissPolicy(HbPopup::TapAnywhere);
       
   101         q_ptr->setTimeout(timeoutValue(HbPopup::StandardTimeout));
       
   102         // Use default primary button, secondary button is empty
       
   103         if (!mDefaultActions[AcceptButton]) {
       
   104             mDefaultActions[AcceptButton] = new HbAction(0);
       
   105         }
       
   106         mActions[AcceptButton].mAction = mDefaultActions[AcceptButton];
       
   107         break;
       
   108     case HbMessageBox::MessageTypeQuestion:
       
   109         q_ptr->setTimeout(HbPopup::NoTimeout);
       
   110         q_ptr->setDismissPolicy(HbPopup::NoDismiss);
       
   111         // Use default primary and secondary buttons
       
   112         for(int i = 0; i < NumActions; i++) {
       
   113             if (!mDefaultActions[i]) {
       
   114                 mDefaultActions[i] = new HbAction(0);
       
   115             }
       
   116             mActions[i].mAction = mDefaultActions[i];
       
   117         }
       
   118         break;
       
   119     default:
       
   120         Q_ASSERT(false);
       
   121     }
       
   122 }
       
   123 
       
   124 void HbDeviceMessageBoxPrivate::setAction(ActionSelector select, QAction *action)
       
   125 {
       
   126     TRACE_ENTRY
       
   127     Action &dialogAction = mActions[select];
       
   128     dialogAction.mFlags = Modified;
       
   129     dialogAction.mAction = action;
       
   130     TRACE_EXIT
       
   131 }
       
   132 
       
   133 // Send properties to server
       
   134 void HbDeviceMessageBoxPrivate::sendToServer(bool show)
       
   135 {
       
   136     killTimer(mUpdateTimerId);
       
   137     mUpdateTimerId = 0;
       
   138 
       
   139     // If this is update but show has not been called, return.
       
   140     if (!show && !mVisible) {
       
   141       return;
       
   142     }
       
   143 
       
   144     // If this is update but no properties have been mofified, return
       
   145     if (!show && !propertiesModified()) {
       
   146         return;
       
   147     }
       
   148 
       
   149     // If this is a show, send type property
       
   150     if (show) {
       
   151         mProperties[Type].mFlags = Modified;
       
   152     }
       
   153 
       
   154     static const char * const propertyNames[] = {
       
   155         "type",
       
   156         "text",
       
   157         "iconName",
       
   158         "iconAlignment",
       
   159         "iconVisible",
       
   160         "timeout",
       
   161         "dismissPolicy",
       
   162         "animationDefinition"
       
   163     };
       
   164 
       
   165     QVariantMap parameters;
       
   166     for(int i = 0; i < NumProperties; i++) {
       
   167         if (mProperties[i].mFlags & Modified) {
       
   168             if (show || !(mProperties[i].mFlags & SentToServer)) {
       
   169                 parameters.insert(propertyNames[i], mProperties[i].mValue);
       
   170                 mProperties[i].mFlags |= SentToServer;
       
   171             }
       
   172         }
       
   173     }
       
   174 
       
   175     static const char * const actionNames[] = {
       
   176         "primaryActionText",
       
   177         "secondaryActionText"
       
   178     };
       
   179     static const char * const nullActionNames[] = {
       
   180         "primaryActionNull",
       
   181         "secondaryActionNull"
       
   182     };
       
   183 
       
   184     for(int i = 0; i < NumActions; i++) {
       
   185         if (mActions[i].mFlags & Modified) {
       
   186             if (show || !(mActions[i].mFlags & SentToServer)) {
       
   187                 if (mActions[i].mAction) {
       
   188                     parameters.insert(actionNames[i], mActions[i].mAction->text());
       
   189                 } else {
       
   190                     parameters.insert(nullActionNames[i], true);
       
   191                 }
       
   192                 mActions[i].mFlags |= SentToServer;
       
   193             }
       
   194         }
       
   195     }
       
   196 
       
   197     if (show) {
       
   198         for(int i = 0; i < NumActions; i++) {
       
   199             mActions[i].mTriggered = false;
       
   200         }
       
   201         if (mDeviceDialog->show("com.nokia.hb.devicemessagebox/1.0", parameters)) {
       
   202             mVisible = true;
       
   203         } else { // failed to show device dialog. Start a one shot to emit aboutToClose() signal.
       
   204             QTimer::singleShot(0, q_ptr, SIGNAL(aboutToClose()));
       
   205         }
       
   206     } else {
       
   207         mDeviceDialog->update(parameters);
       
   208     }
       
   209 }
       
   210 
       
   211 // Check if any properties have been modified
       
   212 bool HbDeviceMessageBoxPrivate::propertiesModified() const
       
   213 {
       
   214     for(int i = 0; i < NumProperties; i++) {
       
   215         if ((mProperties[i].mFlags & Modified) && !(mProperties[i].mFlags & SentToServer)) {
       
   216             return true;
       
   217         }
       
   218     }
       
   219     for(int i = 0; i < NumActions; i++) {
       
   220         if ((mActions[i].mFlags & Modified) && !(mActions[i].mFlags & SentToServer)) {
       
   221             return true;
       
   222         }
       
   223     }
       
   224     return false;
       
   225 }
       
   226 
       
   227 // Clear actions
       
   228 void HbDeviceMessageBoxPrivate::clearActions()
       
   229 {
       
   230     for(int i = 0; i < NumActions; i++) {
       
   231         mActions[i].mAction = 0;
       
   232         mActions[i].mFlags = NoFlags;
       
   233         mActions[i].mTriggered = false;
       
   234     }
       
   235 }
       
   236 
       
   237 void HbDeviceMessageBoxPrivate::close()
       
   238 {
       
   239     TRACE_ENTRY
       
   240     mDeviceDialog->cancel();
       
   241     mVisible = false;
       
   242     TRACE_EXIT
       
   243     return;
       
   244 }
       
   245 
       
   246 void HbDeviceMessageBoxPrivate::exec()
       
   247 {
       
   248     TRACE_ENTRY
       
   249     sendToServer(true);
       
   250     mDeviceDialog->waitForClosed();
       
   251     TRACE_EXIT
       
   252 }
       
   253 
       
   254 void HbDeviceMessageBoxPrivate::triggerAction(QVariantMap data)
       
   255 {
       
   256     TRACE_ENTRY
       
   257     const char *key = "act";
       
   258     QVariantMap::const_iterator i = data.find(key);
       
   259     if (i != data.constEnd()) {
       
   260         QAction *action;
       
   261         if (i.value().toString() == "p") {
       
   262             mActions[AcceptButton].mTriggered = true;
       
   263             action = mActions[AcceptButton].mAction;
       
   264         } else {
       
   265             mActions[RejectButton].mTriggered = true;
       
   266             action = mActions[RejectButton].mAction;
       
   267         }
       
   268         if (action) {
       
   269             action->trigger();
       
   270         }
       
   271     }
       
   272     TRACE_EXIT
       
   273 }
       
   274 
       
   275 void HbDeviceMessageBoxPrivate::setProperty(PropertySelector propertySelector, int value)
       
   276 {
       
   277     Property &property = mProperties[propertySelector];
       
   278     property.mValue.setValue(value);
       
   279     property.mFlags = Modified;
       
   280     scheduleUpdateEvent();
       
   281 }
       
   282 
       
   283 void HbDeviceMessageBoxPrivate::setProperty(PropertySelector propertySelector,
       
   284     const QString &value)
       
   285 {
       
   286     Property &property = mProperties[propertySelector];
       
   287     property.mValue.setValue(value);
       
   288     property.mFlags = Modified;
       
   289     scheduleUpdateEvent();
       
   290 }
       
   291 
       
   292 // Schedule event to update changed properties to device dialog server. update() is not
       
   293 // called after each time a property is set. Instead an event is scheduled in order to
       
   294 // update all changed properties in one shot.
       
   295 void HbDeviceMessageBoxPrivate::scheduleUpdateEvent()
       
   296 {
       
   297     if (mVisible && mUpdateTimerId == 0) {
       
   298         mUpdateTimerId = startTimer(0);
       
   299     }
       
   300 }
       
   301 
       
   302 void HbDeviceMessageBoxPrivate::timerEvent(QTimerEvent *event)
       
   303 {
       
   304     if (event->timerId() == mUpdateTimerId) {
       
   305         sendToServer(false);
       
   306     }
       
   307 }
       
   308 
       
   309 int HbDeviceMessageBoxPrivate::timeoutValue(HbPopup::DefaultTimeout timeout)
       
   310 {
       
   311     TRACE_STATIC_ENTRY
       
   312 
       
   313     static const struct { HbPopup::DefaultTimeout timeout; int value; } timeoutValues[] = {
       
   314         {HbPopup::NoTimeout,0},
       
   315         {HbPopup::ConfirmationNoteTimeout,1500},
       
   316         {HbPopup::StandardTimeout,3000},
       
   317         {HbPopup::ContextMenuTimeout,6000},
       
   318     };
       
   319     int count = sizeof(timeoutValues) / sizeof(timeoutValues[0]);
       
   320     if (timeout < 0 || timeout >= count) {
       
   321         TRACE_EXIT
       
   322         return timeoutValues[HbPopup::NoTimeout].value;
       
   323     }
       
   324     TRACE_EXIT
       
   325     return timeoutValues[timeout].value;
       
   326 }
       
   327 
       
   328 HbDeviceMessageBoxPrivate::ActionSelector HbDeviceMessageBoxPrivate::actionSelector(
       
   329     HbDeviceMessageBox::ActionRole role)
       
   330 {
       
   331     static const ActionSelector selectors[] = {
       
   332         AcceptButton, RejectButton
       
   333     };
       
   334     const unsigned numSelectors = sizeof(selectors) / sizeof(selectors[0]);
       
   335     unsigned index = role;
       
   336     if (index >= numSelectors) {
       
   337         Q_ASSERT(false);
       
   338         return InvalidSelector;
       
   339     }
       
   340     else {
       
   341         return selectors[index];
       
   342     }
       
   343 }
       
   344 
       
   345 // Temporary until HbAction is deprecated out from device message box API
       
   346 // Tbd. remove when deprecation period ends
       
   347 HbAction *HbDeviceMessageBoxPrivate::toHbAction(QAction *action)
       
   348 {
       
   349     // Upcast to HbAction
       
   350     HbAction *hbAction = qobject_cast<HbAction*>(action);
       
   351     // Warn if user has mixed HbAction and QAction APis
       
   352     if (action != hbAction) {
       
   353         //qWarning("HbDeviceMessageBox: HbAction API:s deprecated! Returning QAction instead of HbAction");
       
   354         // Best option is to return QAction and hope caller doesn't use HbAction parts
       
   355         hbAction = reinterpret_cast<HbAction*>(action);
       
   356     }
       
   357     return hbAction;
       
   358 }
       
   359 
       
   360 /*!
       
   361     \class HbDeviceMessageBox
       
   362     \brief HbDeviceMessageBox is a device dialog version of HbMessageBox.
       
   363 
       
   364     It displays a message box with text, icon or animation and optional reply button(s).
       
   365 
       
   366     Device dialogs are shown on top of any running applications and are always modal by nature.
       
   367 
       
   368     HbDeviceMessageBox provides a similar kind of interface as HbMessageBox,
       
   369     excluding functions which handle concrete UI-component related information.
       
   370 
       
   371     A device message box is launched when exec() for synchronous dialog or show() for asynchronous
       
   372     dialog is called. Launched dialog can be updated by setters. Because updating a dialog
       
   373     requires interprocess communication, it's advisable to fully construct the device message box before
       
   374     calling show(). Device message box is closed when user dismisses it with pressing a button, when
       
   375     client calls close() or the dialog reaches timeout. If the system must close the device message
       
   376     box while it is executing, it will have the same effect than having message box's secondary action
       
   377     activated.
       
   378 
       
   379     Static convenience functions are provided for launching message boxes.
       
   380     Dialogs created by them contain a default property values appropriate for
       
   381     the message box type and their contents cannot be updated. Information and
       
   382     warning convenience methods return immediately. Question waits for a message box
       
   383     to close.
       
   384 
       
   385     Supported icon animation formats are following:
       
   386     - GIF (.gif)
       
   387     - MNG (.mng)
       
   388         - Frame animations
       
   389 
       
   390     Sample code:
       
   391 
       
   392     \code
       
   393     // Ask from user whether to continue operation or not.
       
   394     // Uses default accept/reject buttons (yes/no).
       
   395 
       
   396     bool value = HbDeviceMessageBox::question("Continue operation ?");
       
   397     if (value) {
       
   398         continueOperation();
       
   399     }
       
   400     \endcode
       
   401 
       
   402     Alter the appearance of the message box with the methods provided by the class.
       
   403 
       
   404     \code
       
   405     // Code below modifies the default properties of the message box.
       
   406 
       
   407     HbDeviceMessageBox messageBox(HbMessageBox::MessageTypeQuestion);
       
   408     messageBox.setText("End game?");
       
   409     QString fileName("note_warning");
       
   410     messageBox.setIconName(fileName);
       
   411     Qt::Alignment align(Qt::AlignLeft|Qt::AlignTop);
       
   412     messageBox.setIconAlignment(align);
       
   413 
       
   414     QAction acceptAction("Ok", 0);
       
   415     messageBox.setAction(&acceptAction, HbDeviceMessageBox::AcceptButtonRole);
       
   416     QAction rejectAction("Cancel", 0);
       
   417     messageBox.setAction(&rejectAction, HbDeviceMessageBox::RejectButtonRole);
       
   418 
       
   419     // Beware, application may exit during exec().
       
   420     // Beware, exec() is not compatible with gestures.
       
   421     QAction *result = messageBox.exec();
       
   422     bool quit = messageBox.isAcceptAction(result);
       
   423     if (quit) {
       
   424         quit();
       
   425     }
       
   426     \endcode
       
   427 
       
   428     Creating a frame animation.
       
   429 
       
   430     Create an animation definition file:
       
   431     \code
       
   432     <animations>
       
   433         <icon name="frame_anim_looping" playmode="loop">
       
   434             <frame duration="100">c:\icon1.svg</frame>
       
   435             <frame duration="200">c:\icon2.svg</frame>
       
   436             <frame duration="300">c:\icon3.svg</frame>
       
   437             </icon>
       
   438     </animations>
       
   439     \endcode
       
   440 
       
   441     Create HbDeviceMessageBox in a way described before and
       
   442     set definition file and animation's logical name.
       
   443 
       
   444     \code
       
   445     QString animationDefinitionXML("c:\animation.axml");
       
   446     QString logicalIconName("frame_anim_looping");
       
   447 
       
   448     msg->setAnimationDefinition(animationDefinitionXML);
       
   449     msg->setIconName(logicalIconName);
       
   450     msg->show();
       
   451     \endcode
       
   452 
       
   453     \sa HbMessageBox, HbDialog, HbDeviceDialog
       
   454 
       
   455     @proto
       
   456     @hbwidgets
       
   457 */
       
   458 
       
   459 /*!
       
   460     \fn void HbDeviceMessageBox::aboutToClose();
       
   461 
       
   462     This signal is emitted when the device message box is about to be closed i.e.
       
   463     when the question type of message is replied to by the user.
       
   464  */
       
   465 
       
   466 /*!
       
   467     \enum HbDeviceMessageBox::ActionRole
       
   468     Defines roles for actions set into a message box.
       
   469 */
       
   470 /*!
       
   471     \var HbDeviceMessageBox::ActionRole HbDeviceMessageBox::InvalidRole
       
   472     No action.
       
   473 */
       
   474 /*!
       
   475     \var HbDeviceMessageBox::ActionRole HbDeviceMessageBox::AcceptButtonRole
       
   476     Accept button action.
       
   477 */
       
   478 /*!
       
   479     \var HbDeviceMessageBox::ActionRole HbDeviceMessageBox::RejectButtonRole
       
   480     Reject button action.
       
   481 */
       
   482 
       
   483 /*!
       
   484     Constructor.
       
   485     \param type Type of the message box.
       
   486     \param parent An optional parameter.
       
   487 */
       
   488 HbDeviceMessageBox::HbDeviceMessageBox(HbMessageBox::MessageBoxType type, QObject *parent) :
       
   489     QObject(parent), d_ptr(new HbDeviceMessageBoxPrivate)
       
   490 {
       
   491     TRACE_ENTRY
       
   492     d_ptr->q_ptr = this;
       
   493     d_ptr->mProperties[HbDeviceMessageBoxPrivate::Type].mValue.setValue(static_cast<int>(type));
       
   494     d_ptr->init();
       
   495     TRACE_EXIT
       
   496 }
       
   497 
       
   498 /*!
       
   499     Constructor.
       
   500     \param text Text can be set in the constructor.
       
   501     \param type Type of the message box.
       
   502     \param parent An optional parameter.
       
   503 */
       
   504 HbDeviceMessageBox::HbDeviceMessageBox(const QString &text, HbMessageBox::MessageBoxType type,
       
   505     QObject *parent) : QObject(parent), d_ptr(new HbDeviceMessageBoxPrivate)
       
   506 {
       
   507     TRACE_ENTRY
       
   508     d_ptr->q_ptr = this;
       
   509     d_ptr->mProperties[HbDeviceMessageBoxPrivate::Type].mValue.setValue(static_cast<int>(type));
       
   510     d_ptr->init();
       
   511     setText(text);
       
   512     TRACE_EXIT
       
   513 }
       
   514 
       
   515 /*!
       
   516     Destructs the class.
       
   517 */
       
   518 HbDeviceMessageBox::~HbDeviceMessageBox()
       
   519 {
       
   520     TRACE_ENTRY
       
   521     delete d_ptr;
       
   522     TRACE_EXIT
       
   523 }
       
   524 
       
   525 /*!
       
   526     Executes the dialog asynchronously.
       
   527 */
       
   528 void HbDeviceMessageBox::show()
       
   529 {
       
   530     TRACE_ENTRY
       
   531     d_ptr->sendToServer(true);
       
   532     TRACE_EXIT
       
   533 }
       
   534 
       
   535 /*!
       
   536     Updates changed properties of a launched message box to device dialog service using
       
   537     interprocess communication. Has no effect if show() has not been called or dialog has
       
   538     closed already. Calling show() is optional as updating any property schedules an event
       
   539     and the dialog is updated next time Qt event loop executes.
       
   540 
       
   541     \sa show()
       
   542 */
       
   543 void HbDeviceMessageBox::update()
       
   544 {
       
   545     d_ptr->sendToServer(false);
       
   546 }
       
   547 
       
   548 /*!
       
   549     Closes the dialog if the dialog is shown asynchronously.
       
   550 */
       
   551 void HbDeviceMessageBox::close()
       
   552 {
       
   553     TRACE_ENTRY
       
   554     d_ptr->close();
       
   555     TRACE_EXIT
       
   556 }
       
   557 
       
   558 /*!
       
   559     Executes the dialog synchronously.
       
   560 
       
   561     Returns a pointer to the action that was activated by the user, i.e. dialog's
       
   562     primary or secondary action.
       
   563 
       
   564     This functions starts a new event loop. Consider following caveats before using it
       
   565     Stack usage increases. Depending on application program flow, several event
       
   566     loops may get instantiated on top of each other. Application event processing continues while
       
   567     exec() executes. When it returns application state may have changed. For example some
       
   568     objects may have been deleted or application may have exited.
       
   569 
       
   570     \sa primaryAction(), setPrimaryAction(), secondaryAction(), setSecondaryAction()
       
   571 
       
   572     <b>Note that starting an event loop isn't compatible with gestures.</b> Therefore if an application
       
   573     has an user interface, please don't use this function. Instead connect to signals and use
       
   574     asynchronous show().
       
   575 
       
   576     \deprecated HbDeviceMessageBox::exec()
       
   577     is deprecated. Replaced by const QAction *HbDeviceMessageBox::exec() const.
       
   578 
       
   579 */
       
   580 HbAction *HbDeviceMessageBox::exec()
       
   581 {
       
   582     TRACE_ENTRY
       
   583     HbDeviceMessageBox &box = const_cast<HbDeviceMessageBox&>(*this);
       
   584     QAction *action;
       
   585     QPointer<HbDeviceMessageBoxPrivate> guard = d_ptr;
       
   586     box.d_ptr->exec();
       
   587     if (guard.isNull()) {
       
   588         action = 0;
       
   589     } else if (box.d_ptr->mActions[HbDeviceMessageBoxPrivate::AcceptButton].mTriggered) {
       
   590         action = box.d_ptr->mActions[HbDeviceMessageBoxPrivate::AcceptButton].mAction;
       
   591     } else {
       
   592         action = box.d_ptr->mActions[HbDeviceMessageBoxPrivate::RejectButton].mAction;
       
   593     }
       
   594     TRACE_EXIT
       
   595     return HbDeviceMessageBoxPrivate::toHbAction(action);
       
   596 }
       
   597 
       
   598 /*!
       
   599     Executes the dialog synchronously.
       
   600 
       
   601     Returns a pointer to the action that was activated by the user, i.e. dialog's
       
   602     accept or reject action. Return 0 if object was deleted during a call.
       
   603 
       
   604     This functions starts a new event loop. Consider following caveats before using it
       
   605     Stack usage increases. Depending on application program flow, several event
       
   606     loops may get instantiated on top of each other. Application event processing continues while
       
   607     exec() executes. When it returns application state may have changed. For example some
       
   608     objects may have been deleted or application may have exited.
       
   609 
       
   610     <b>Note that starting an event loop isn't compatible with gestures.</b> Therefore if an application
       
   611     has an user interface, please don't use this function. Instead connect to signals and use
       
   612     asynchronous show().
       
   613 
       
   614     \sa action(), setAction()
       
   615 */
       
   616 const QAction *HbDeviceMessageBox::exec() const
       
   617 {
       
   618     TRACE_ENTRY
       
   619     const QAction *action;
       
   620     QPointer<HbDeviceMessageBoxPrivate> guard = d_ptr;
       
   621     d_ptr->exec();
       
   622     if (guard.isNull()) {
       
   623         action = 0;
       
   624     } else {
       
   625         action = triggeredAction();
       
   626     }
       
   627     TRACE_EXIT
       
   628     return action;
       
   629 }
       
   630 
       
   631 /*!
       
   632     Returns an action user triggered causing the dialog to close. Returns 0 if none of the actions were
       
   633     triggered and dialog was closed for other reason.
       
   634 
       
   635     \sa show(), exec(), action(), isAcceptAction()
       
   636 */
       
   637 const QAction *HbDeviceMessageBox::triggeredAction() const
       
   638 {
       
   639     for(int i = 0; i < HbDeviceMessageBoxPrivate::NumActions; i++) {
       
   640         if (d_ptr->mActions[i].mTriggered) {
       
   641             return d_ptr->mActions[i].mAction;
       
   642         }
       
   643     }
       
   644     return 0;
       
   645 }
       
   646 
       
   647 /*!
       
   648     Returns true if an action is an accept action. This function should be used to check whether
       
   649     user accepted message box by triggering accept action. In the future there could be several
       
   650     accept actions instead of only one.
       
   651 
       
   652     \sa exec(), action(), triggeredAction()
       
   653 */
       
   654 bool HbDeviceMessageBox::isAcceptAction(const QAction *action) const
       
   655 {
       
   656     return action && action == d_ptr->mActions[HbDeviceMessageBoxPrivate::AcceptButton].mAction;
       
   657 }
       
   658 
       
   659 /*!
       
   660     Sets message box type. All message box properties are reset to a default values for the type.
       
   661     A show() must be called to launch a message box after setMessageBoxType() has been called.
       
   662 
       
   663     \param type Message box type.
       
   664 
       
   665     \sa setMessageBoxType()
       
   666 */
       
   667 void HbDeviceMessageBox::setMessageBoxType(HbMessageBox::MessageBoxType type)
       
   668 {
       
   669     TRACE_ENTRY
       
   670     // After setType(), a new message is launched by a show()
       
   671     d_ptr->mVisible = false;
       
   672     d_ptr->mProperties[HbDeviceMessageBoxPrivate::Type].mValue.setValue(static_cast<int>(type));
       
   673     // All properties initialized to default
       
   674     d_ptr->initProperties();
       
   675     TRACE_EXIT
       
   676 }
       
   677 
       
   678 /*!
       
   679     Returns message box type.
       
   680 
       
   681     \sa setMessageBoxType()
       
   682 */
       
   683 HbMessageBox::MessageBoxType HbDeviceMessageBox::messageBoxType() const
       
   684 {
       
   685     return static_cast<HbMessageBox::MessageBoxType>
       
   686         (d_ptr->mProperties[HbDeviceMessageBoxPrivate::Type].mValue.toInt());
       
   687 }
       
   688 
       
   689 /*!
       
   690     Convenience method for showing question message box and waiting for it to close.
       
   691 
       
   692     This functions starts a new event loop. Consider following caveats before using it
       
   693     Stack usage increases. Depending on application program flow, several event
       
   694     loops may get instantiated on top of each other. Application event processing continues while
       
   695     question() executes. When it returns application state may have changed. For example some
       
   696     objects may have been deleted or application may have exited.
       
   697 
       
   698     <b>Note that starting an event loop isn't compatible with gestures.</b> Therefore if an application
       
   699     has an user interface, please don't use this function. Instead connect to signals and use
       
   700     asynchronous show().
       
   701 
       
   702     \param text - text shown in message box.
       
   703     \param acceptButtonText Accept button text. If string is null, a default button is used.
       
   704     \param rejectButtonText Reject button text. If string is null, a default button is used.
       
   705 
       
   706     Returns true if user triggered accept action, otherwise false.
       
   707 
       
   708     \sa show()
       
   709 */
       
   710 bool HbDeviceMessageBox::question(
       
   711     const QString &text,
       
   712     const QString &acceptButtonText,
       
   713     const QString &rejectButtonText)
       
   714 {
       
   715     TRACE_STATIC_ENTRY
       
   716     HbDeviceMessageBox messageBox(HbMessageBox::MessageTypeQuestion);
       
   717     messageBox.setText(text);
       
   718 
       
   719     if (!acceptButtonText.isNull()) {
       
   720         messageBox.setAction(new QAction(acceptButtonText, &messageBox), AcceptButtonRole);
       
   721     }
       
   722     if (!rejectButtonText.isNull()) {
       
   723         messageBox.setAction(new QAction(rejectButtonText, &messageBox), RejectButtonRole);
       
   724     }
       
   725 
       
   726     // Tbd. Temporary until deprecated HbAction *HbDeviceMessageBox::exec() is removed.
       
   727     const HbDeviceMessageBox &tmp = const_cast<const HbDeviceMessageBox&>(messageBox);
       
   728     tmp.exec();
       
   729     TRACE_EXIT
       
   730     // Return true if accept action was triggered
       
   731     return messageBox.isAcceptAction(messageBox.triggeredAction());
       
   732 }
       
   733 
       
   734 /*!
       
   735     Convenience method for showing information message box. Launches a message box and
       
   736     returns immediately.
       
   737 
       
   738     \param text - text shown in message box.
       
   739 */
       
   740 void HbDeviceMessageBox::information(const QString &text)
       
   741 {
       
   742     TRACE_STATIC_ENTRY
       
   743     HbDeviceMessageBox(text, HbMessageBox::MessageTypeInformation).show();
       
   744     TRACE_EXIT
       
   745 }
       
   746 
       
   747 /*!
       
   748     Convenience method for showing warning message box. Launches a message box and returns
       
   749     immediately.
       
   750 
       
   751     \param text - text shown in message box.
       
   752 */
       
   753 void HbDeviceMessageBox::warning(const QString &text)
       
   754 {
       
   755     TRACE_STATIC_ENTRY
       
   756     HbDeviceMessageBox(text, HbMessageBox::MessageTypeWarning).show();
       
   757     TRACE_EXIT
       
   758 }
       
   759 
       
   760 /*!
       
   761     Returns device message box primary action.
       
   762 
       
   763     \sa setPrimaryAction()
       
   764 
       
   765     \deprecated HbDeviceMessageBox::primaryAction()
       
   766     is deprecated. Replaced by HbDeviceMessageBox::action(ActionRole role) const.
       
   767 
       
   768 */
       
   769 HbAction* HbDeviceMessageBox::primaryAction() const
       
   770 {
       
   771     //qWarning("HbDeviceMessageBox: HbAction API:s deprecated! Use action()");
       
   772     return HbDeviceMessageBoxPrivate::toHbAction(
       
   773         d_ptr->mActions[HbDeviceMessageBoxPrivate::AcceptButton].mAction);
       
   774 }
       
   775 
       
   776 /*!
       
   777     Sets the given action to the device message box.
       
   778     Action is added to the left side of the dialog if the layout direction of the
       
   779     application is left-to-right and in the vice-versa if the layout direction
       
   780     of the application is right-to-left. Action can be set to null which means
       
   781     that action and a button related to this action are removed from the dialog.
       
   782     Only the text of the action is shown in the message box. Icon of the action
       
   783     is not used. The message box does not take ownership of the given QAction.
       
   784 
       
   785     HbDeviceMessageBox constructor sets a default action into the message box.
       
   786 
       
   787     \param action Action or null. Ownership doesn't transfer.
       
   788 
       
   789     \sa primaryAction()
       
   790 
       
   791     \deprecated HbDeviceMessageBox::setPrimaryAction(HbAction *action)
       
   792     is deprecated. HbDeviceMessageBox::setAction(QAction *action, ActionRole role).
       
   793 
       
   794 */
       
   795 void HbDeviceMessageBox::setPrimaryAction(HbAction *action)
       
   796 {
       
   797     TRACE_ENTRY
       
   798     //qWarning("HbDeviceMessageBox: HbAction API:s deprecated! Use setAction()");
       
   799     d_ptr->setAction(HbDeviceMessageBoxPrivate::AcceptButton, action);
       
   800     d_ptr->scheduleUpdateEvent();
       
   801     TRACE_EXIT
       
   802 }
       
   803 
       
   804 /*!
       
   805     Returns device message box secondary action.
       
   806 
       
   807     \sa setSecondaryAction()
       
   808 
       
   809     \deprecated HbDeviceMessageBox::secondaryAction()
       
   810     is deprecated. Replaced by HbDeviceMessageBox::action(ActionRole role) const.
       
   811 
       
   812 */
       
   813 HbAction* HbDeviceMessageBox::secondaryAction() const
       
   814 {
       
   815     //qWarning("HbDeviceMessageBox: HbAction API:s deprecated! Use action()");
       
   816     return HbDeviceMessageBoxPrivate::toHbAction(
       
   817         d_ptr->mActions[HbDeviceMessageBoxPrivate::RejectButton].mAction);
       
   818 }
       
   819 
       
   820 /*!
       
   821     Adds the given action to the device message box.
       
   822     Action is added to the right side of the dialog if the layout direction of the
       
   823     application is left-to-right and in the vice-versa if the layout direction
       
   824     of the application is right-to-left. Action can be set to null which means
       
   825     that action and a button related to this action are removed from the dialog.
       
   826     Only the text of the action is shown in the message box. Icon of the action
       
   827     is not used. The message box does not take ownership of given QAction.
       
   828 
       
   829     HbDeviceMessageBox constructor sets a default action into question message
       
   830     box. Information and warning message boxes don't have a default secondary action.
       
   831 
       
   832     \param action Action or null.
       
   833 
       
   834     \sa secondaryAction()
       
   835 
       
   836     \deprecated HbDeviceMessageBox::setSecondaryAction(HbAction *action)
       
   837     is deprecated. HbDeviceMessageBox::setAction(QAction *action, ActionRole role).
       
   838 */
       
   839 void HbDeviceMessageBox::setSecondaryAction(HbAction *action)
       
   840 {
       
   841     TRACE_ENTRY
       
   842     //qWarning("HbDeviceMessageBox: HbAction API:s deprecated! Use setAction()");
       
   843     d_ptr->setAction(HbDeviceMessageBoxPrivate::RejectButton, action);
       
   844     d_ptr->scheduleUpdateEvent();
       
   845     TRACE_EXIT
       
   846 }
       
   847 
       
   848 /*!
       
   849     Returns device message box action. The action returned may be a default
       
   850     action that message box has set at constructor or one set by setAction().
       
   851 
       
   852     \param role Selects an action to get.
       
   853 
       
   854     \sa setAction()
       
   855 */
       
   856 QAction *HbDeviceMessageBox::action(ActionRole role) const
       
   857 {
       
   858     HbDeviceMessageBoxPrivate::ActionSelector  actionSelector =
       
   859         HbDeviceMessageBoxPrivate::actionSelector(role);
       
   860     return actionSelector != HbDeviceMessageBoxPrivate::InvalidSelector ?
       
   861         d_ptr->mActions[actionSelector].mAction : 0;
       
   862 }
       
   863 
       
   864 /*!
       
   865     Sets an action into the device message box. Action role is either an
       
   866     accept (left button in left-to-right layout) or reject (right button).
       
   867     Action can be null which removes corresponding button from the message
       
   868     box. Only text of the action is shown in the message box button. Icon
       
   869     of the action is not used. The message box does not take ownership of
       
   870     the action.
       
   871 
       
   872     HbDeviceMessageBox constructor sets a default accept and reject actions into
       
   873     question message box. Information and warning message boxes have only accept
       
   874     action by default. Default actions are owned and deleted by the message box.
       
   875 
       
   876     \param action Action or null. Ownership does not transfer.
       
   877     \param role Selects an action to set.
       
   878 
       
   879     \sa action()
       
   880 */
       
   881 void HbDeviceMessageBox::setAction(QAction *action, ActionRole role)
       
   882 {
       
   883     TRACE_ENTRY
       
   884     HbDeviceMessageBoxPrivate::ActionSelector  actionSelector =
       
   885         HbDeviceMessageBoxPrivate::actionSelector(role);
       
   886     if (actionSelector != HbDeviceMessageBoxPrivate::InvalidSelector) {
       
   887         d_ptr->setAction(HbDeviceMessageBoxPrivate::actionSelector(role), action);
       
   888         d_ptr->scheduleUpdateEvent();
       
   889     }
       
   890     TRACE_EXIT
       
   891 }
       
   892 
       
   893 /*!
       
   894     Sets text of the message dialog.
       
   895 
       
   896     \param text Message text.
       
   897 
       
   898     \sa text()
       
   899 */
       
   900 void HbDeviceMessageBox::setText(const QString &text)
       
   901 {
       
   902     TRACE_ENTRY
       
   903     d_ptr->setProperty(HbDeviceMessageBoxPrivate::Text, text);
       
   904     TRACE_EXIT
       
   905 }
       
   906 
       
   907 /*!
       
   908     Returns text of the dialog.
       
   909 
       
   910     \sa setText()
       
   911 */
       
   912 QString HbDeviceMessageBox::text() const
       
   913 {
       
   914     return d_ptr->mProperties[HbDeviceMessageBoxPrivate::Text].mValue.toString();
       
   915 }
       
   916 
       
   917 /*!
       
   918     Sets message box icon name or animation logical name.
       
   919 
       
   920     \param aIconName Icon name. Icon can be from Hb resources or themes. Or can be a file in
       
   921     a file system.
       
   922 
       
   923     \sa IconName()
       
   924 */
       
   925 void HbDeviceMessageBox::setIconName(const QString &iconName)
       
   926 {
       
   927     TRACE_ENTRY
       
   928     d_ptr->setProperty(HbDeviceMessageBoxPrivate::IconName, iconName);
       
   929     TRACE_EXIT
       
   930 }
       
   931 
       
   932 /*!
       
   933     Returns name and path of the icon or animation's logical name.
       
   934 
       
   935     \sa setIconName()
       
   936 */
       
   937 QString HbDeviceMessageBox::iconName() const
       
   938 {
       
   939     return d_ptr->mProperties[HbDeviceMessageBoxPrivate::IconName].mValue.toString();
       
   940 }
       
   941 
       
   942 /*!
       
   943     Sets the icon's alignment in the icon area of the dialog.
       
   944 
       
   945     \param align Qt defined alignment options can used.
       
   946 
       
   947     \sa iconAlignment()
       
   948 */
       
   949 void HbDeviceMessageBox::setIconAlignment(Qt::Alignment align)
       
   950 {
       
   951     TRACE_ENTRY
       
   952     d_ptr->setProperty(HbDeviceMessageBoxPrivate::IconAlignment, align);
       
   953     TRACE_EXIT
       
   954 }
       
   955 
       
   956 /*!
       
   957     Returns the icon alignment in the icon area of the dialog.
       
   958 
       
   959     The default value is \c Qt::AlignCenter.
       
   960 
       
   961     \sa setIconAlignment()
       
   962 */
       
   963 Qt::Alignment HbDeviceMessageBox::iconAlignment() const
       
   964 {
       
   965     return static_cast<Qt::Alignment>
       
   966         (d_ptr->mProperties[HbDeviceMessageBoxPrivate::IconAlignment].mValue.toInt());
       
   967 }
       
   968 
       
   969 /*!
       
   970     Enables/disables icon visibility.
       
   971 
       
   972     \param visible Enables icon visibility.
       
   973 
       
   974     \sa iconVisible()
       
   975 */
       
   976 void HbDeviceMessageBox::setIconVisible(bool visible)
       
   977 {
       
   978     TRACE_ENTRY
       
   979     d_ptr->setProperty(HbDeviceMessageBoxPrivate::IconVisible, visible);
       
   980     TRACE_EXIT
       
   981 }
       
   982 
       
   983 /*!
       
   984     Returns true if icon is visible.
       
   985 
       
   986     \sa setIconVisible()
       
   987 */
       
   988 bool HbDeviceMessageBox::iconVisible() const
       
   989 {
       
   990     return d_ptr->mProperties[HbDeviceMessageBoxPrivate::IconVisible].mValue.toBool();
       
   991 }
       
   992 
       
   993 /*!
       
   994     Sets the timeout property in milliseconds.
       
   995     If timeout <= 0 then the note is permanent and not closed automatically.
       
   996 
       
   997     \param timeout Timeout in milliseconds.
       
   998 
       
   999     \sa timeout() setTimeout(HbPopup::DefaultTimeout)
       
  1000 */
       
  1001 void HbDeviceMessageBox::setTimeout(int timeout)
       
  1002 {
       
  1003     TRACE_ENTRY
       
  1004     d_ptr->setProperty(HbDeviceMessageBoxPrivate::Timeout, timeout);
       
  1005     TRACE_EXIT
       
  1006 }
       
  1007 
       
  1008 /*!
       
  1009     This is a convenience overload of \a timeout() for setting HbPopup::DefaultTimeout values
       
  1010     to achive common look & feel.
       
  1011 
       
  1012     \param timeout Timeout as an enumerated constant.
       
  1013 
       
  1014     \sa enum HbPopup::DefaultTimeout timeout() setTimeout(int)
       
  1015 */
       
  1016 void HbDeviceMessageBox::setTimeout(HbPopup::DefaultTimeout timeout)
       
  1017 {
       
  1018     TRACE_ENTRY
       
  1019     setTimeout(HbDeviceMessageBoxPrivate::timeoutValue(timeout));
       
  1020     TRACE_EXIT
       
  1021 }
       
  1022 
       
  1023 /*!
       
  1024     Returns the timeout property in milliseconds.
       
  1025     If this property is not set the default is HbPopup::StandardTimeout except for
       
  1026     HbMessageBox::MessageTypeQuestion type of message box for which default is HbPopup::NoTimeout.
       
  1027 
       
  1028     \sa setTimeout()
       
  1029 */
       
  1030 int HbDeviceMessageBox::timeout() const
       
  1031 {
       
  1032     return d_ptr->mProperties[HbDeviceMessageBoxPrivate::Timeout].mValue.toInt();
       
  1033 }
       
  1034 
       
  1035 /*!
       
  1036     Sets the dismiss policy for the dialog.
       
  1037 
       
  1038     \param dismissPolicy Dismiss policy of the message box.
       
  1039 
       
  1040     \sa dismissPolicy()
       
  1041 */
       
  1042 void HbDeviceMessageBox::setDismissPolicy(HbPopup::DismissPolicy dismissPolicy)
       
  1043 {
       
  1044     TRACE_ENTRY
       
  1045     d_ptr->setProperty(HbDeviceMessageBoxPrivate::DismissPolicy, dismissPolicy);
       
  1046     TRACE_EXIT
       
  1047 }
       
  1048 
       
  1049 /*!
       
  1050     Returns the dismiss policy of the dialog.
       
  1051     Default is HbPopup::TapAnywhere except for HbMessageBox::MessageTypeQuestion type of
       
  1052     message box for which default is HbPopup::NoDismiss.
       
  1053 
       
  1054     \sa setDismissPolicy()
       
  1055 */
       
  1056 HbPopup::DismissPolicy HbDeviceMessageBox::dismissPolicy() const
       
  1057 {
       
  1058     return static_cast<HbPopup::DismissPolicy>
       
  1059         (d_ptr->mProperties[HbDeviceMessageBoxPrivate::DismissPolicy].mValue.toInt());
       
  1060 }
       
  1061 
       
  1062 /*!
       
  1063     Sets animation definition to a dialog. Animation's logical name has to be set
       
  1064     using setIcon(). Animation definition files must be stored to a place where they
       
  1065     can be accessed by device dialog service.
       
  1066 
       
  1067     Supported animation formats are following:
       
  1068     - GIF (.gif)
       
  1069     - MNG (.mng)
       
  1070         - Frame animations
       
  1071 
       
  1072     \param animationDefinition Path and name of the animation definition file.
       
  1073 
       
  1074     \sa setIcon(), animationDefinition(), HbIconAnimationManager::addDefinitionFile()
       
  1075 */
       
  1076 void HbDeviceMessageBox::setAnimationDefinition(QString &animationDefinition)
       
  1077 {
       
  1078     TRACE_ENTRY
       
  1079     d_ptr->setProperty(HbDeviceMessageBoxPrivate::AnimationDefinition, animationDefinition);
       
  1080     TRACE_EXIT
       
  1081 }
       
  1082 
       
  1083 /*!
       
  1084     Returns animation definition file name.
       
  1085 
       
  1086     \sa setAnimationDefinition()
       
  1087 */
       
  1088 QString HbDeviceMessageBox::animationDefinition() const
       
  1089 {
       
  1090     return d_ptr->mProperties[HbDeviceMessageBoxPrivate::AnimationDefinition].mValue.toString();
       
  1091 }