src/hbcore/devicedialogbase/hbdevicedialog.cpp
changeset 0 16d8024aca5e
child 2 06ff229162e9
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 HbCore 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 /*!
       
    27     \class HbDeviceDialog
       
    28     \brief HbDeviceDialog displays dialogs on top of applications
       
    29 
       
    30     HbDeviceDialog is a concrete class. It can be used directly or as a part of
       
    31     specialization classes for different device dialog types. It's not a widget but interfaces
       
    32     to a device dialog service which is responsible for displaying device dialogs.
       
    33     Device dialog widgets are implemented in plugins loaded by the service.
       
    34 
       
    35     Below is a runtime view of device dialog framework.
       
    36 
       
    37     \dot
       
    38     digraph G {
       
    39 
       
    40         rankdir=LR;
       
    41 
       
    42         subgraph cluster_devicedialog_server {
       
    43             label = "Device Dialog Server";
       
    44             style=filled;
       
    45             color=lightgrey;
       
    46             rank=sink;
       
    47             node [shape = polygon, style=filled, color=white, fontsize = 10];
       
    48             widget1 [label = "hb.devdlg.errordialog/1.0"];
       
    49             widget2 [label = "hb.devdlg.warningdialog/1.0"];
       
    50             node [shape = ellipse, style=filled, color=white, fontsize = 14];
       
    51             deviceDialogManager [label = "DeviceDialog\nmanager"];
       
    52             edge [fontsize = 10, style = dotted];
       
    53             deviceDialogManager -> widget1 [label = ""];
       
    54             deviceDialogManager -> widget2 [label = ""];
       
    55             widget1 -> deviceDialogManager [label = ""];
       
    56             widget2 -> deviceDialogManager [label = ""];
       
    57         }
       
    58 
       
    59         subgraph cluster_client_1 {
       
    60             label = "Client 1";
       
    61             style=filled;
       
    62             color=lightgrey;
       
    63             node [shape = ellipse, style=filled, color=white, fontsize = 14];
       
    64             deviceDialog1 [label = "HbDeviceDialog"];
       
    65         }
       
    66 
       
    67         subgraph cluster_client_2 {
       
    68             label = "Client 2";
       
    69             style=filled;
       
    70             color=lightgrey;
       
    71             node [shape = ellipse, style=filled, color=white, fontsize = 14];
       
    72             deviceDialog2 [label = "HbDeviceDialog"];
       
    73         }
       
    74 
       
    75         subgraph cluster_key {
       
    76             label = "Key";
       
    77             subgraph cluster_key_process1 {
       
    78                 label = "";
       
    79                 style=filled;
       
    80                 color=lightgrey;
       
    81                 node [shape = polygon, style=filled, color=white, fontsize = 10];
       
    82                 key_process1_c0 [label = "Plugin widget"];
       
    83                 node [shape = ellipse, style=filled, color=white, fontsize = 10];
       
    84                 key_process1_c1 [label = "Component"];
       
    85                 edge [style = dotted, fontsize = 10];
       
    86                 key_process1_c1 -> key_process1_c0 [label = "Function call"];
       
    87             }
       
    88             subgraph cluster_key_process2 {
       
    89                 label = "Process";
       
    90                 style=filled;
       
    91                 color=lightgrey;
       
    92                 node [shape = ellipse, style=filled, color=white, fontsize = 10];
       
    93                 key_process2_c0 [label = "Component"];
       
    94                 edge [fontsize = 10];
       
    95                 key_process1_c1 -> key_process2_c0 [label = "Interprocess\ncommunication"];
       
    96             }
       
    97         }
       
    98         edge [style = filled, fontsize = 10];
       
    99         deviceDialog1 -> deviceDialogManager [label = "update"];
       
   100         deviceDialog2 -> deviceDialogManager [label = "update"];
       
   101 
       
   102         edge [style = filled, fontsize = 10];
       
   103         deviceDialogManager -> deviceDialog1 [label = "data"];
       
   104         deviceDialogManager -> deviceDialog2 [label = "data"];
       
   105     }
       
   106     \enddot
       
   107 
       
   108     HbDeviceDialog has no dependencies to other parts of the framework. Only to Qt. Thus it can be used
       
   109     also from engine components that have no user interface.
       
   110 
       
   111     There are three classes of device dialogs. Generic device dialogs which are displayed on top
       
   112     of all applications (incoming call is an exception). Examples of these are "Low memory"
       
   113     message box and "Receive message via bluetooth" query. Device notification dialogs are
       
   114     notifications displayed in a top left corner of a display. Examples are "New message" and
       
   115     "Low battery" notifications. Universal indicator menu shows enhanced status indicator
       
   116     information.
       
   117 
       
   118     Generic device dialogs and indicator menu interrupt current foreground application.
       
   119     User cannot interact with the application with a touch or keyboard until the dialog
       
   120     is dismissed. Device notification dialog behaves differently allowing interaction with the
       
   121     current foreground application.
       
   122 
       
   123     Device dialog widgets are constructed dynamically by the device dialog service. Construction
       
   124     takes two parameters: a type and a set of parameters appropriate to the dialog type.
       
   125     Widgets are implemented by plugins. Device dialog type is an unique string identifying the
       
   126     dialog. A search is made to find a plugin that can instantiate the requested
       
   127     dialog. The service loads the plugin and creates an instance of the widget.
       
   128 
       
   129     Parameter set is encapsulated in QMap<QString, QVariant>. Each device dialog implementation has
       
   130     a default value for all parameters. Only parameters that differ from the default needs to be
       
   131     given. Parameters are <name, value> pairs. How the parameters are used depends on
       
   132     the plugin implementing the dialog. Suggested usage is <name, value> used as property
       
   133     name and value pairs of the dialog implementation. This makes it easy to set properties using
       
   134     QObject::setProperty(const char*, const QVariant&). If data types supported by QVariant are
       
   135     not suitable for a specific device dialog, Q_DECLARE_METATYPE can be used to add data types.
       
   136 
       
   137     Data can be sent to a device dialog after it has been launched using update() function. Data
       
   138     sent by the dialog is received by dataReceived signal. A copy of the last data received
       
   139     is held by the class and can be fetched by a receivedData() function. This allows to receive
       
   140     data without having to connect to a signal by waiting for a dialog to close and then
       
   141     getting the received data.
       
   142 
       
   143     It is possible to launch multiple device dialogs from a single HbDeviceDialog object.
       
   144     However if there is a need to update a dialog or receive data from it, only the last one
       
   145     launched is able to do it. In this case instantiate HbDeviceDialog class for each device dialog
       
   146     that needs communication (update or data receive) after a launch.
       
   147 
       
   148     HbDeviceDialog::show() method returns after device dialog service has accepted the dialog.
       
   149     The service decides when the dialog is actually displayed. If there is no need to receive
       
   150     data from the dialog widget, HbDeviceDialog object can be destroyed after show method returns
       
   151     (can be allocated in a stack). A function is provided to wait for device dialog to be dismissed
       
   152     making the dialog display synchronous.
       
   153 
       
   154     If any signals of HbDeviceDialog are connected, then the instance needs to exist until the
       
   155     dialog is dismissed. In this case device dialog service will close all dialogs
       
   156     launched by the instance when it is deleted making it inappropriate to allocate HbDeviceDialog
       
   157     into a stack.
       
   158 
       
   159     Several clients can share the same device dialog widget by agreeing on an unique tag. See
       
   160     HbDeviceDialogWidgetPlugin for more information.
       
   161 
       
   162     When HbDeviceDialog object is created, it can reserve a communication channel to device dialog
       
   163     service or the channel creation may be delayed until show(). This is controlled by a constructor
       
   164     flag. Default is the delayed resource reservation.
       
   165 
       
   166     HbDeviceDialog class is not thread safe. If cancel() needs to called across threads, a queued
       
   167     signal slot connection can be used.
       
   168 
       
   169     \sa HbDeviceDialogPlugin
       
   170 
       
   171     \beta
       
   172     \hbcore
       
   173 */
       
   174 
       
   175 /*!
       
   176     \enum HbDeviceDialog::DeviceDialogError
       
   177     Defines device dialog error codes and ranges.
       
   178 */
       
   179 /*!
       
   180     \var HbDeviceDialog::DeviceDialogError HbDeviceDialog::FrameworkErrors
       
   181     Start of an error range for errors originating from device dialog framework (client or server).
       
   182 */
       
   183 /*!
       
   184     \var HbDeviceDialog::DeviceDialogError HbDeviceDialog::PluginErrors
       
   185     Start of an error range for errors originating from device dialog plugins. The framework passes
       
   186     these from the plugin unmodified.
       
   187 */
       
   188 /*!
       
   189     \var HbDeviceDialog::DeviceDialogError HbDeviceDialog::ErrorTypeMask
       
   190     Mask for error type part of the error code.
       
   191 */
       
   192 /*!
       
   193     \var HbDeviceDialog::DeviceDialogError HbDeviceDialog::CancelledError
       
   194     Operation was cancelled by cancel().
       
   195 */
       
   196 /*!
       
   197     \var HbDeviceDialog::DeviceDialogError HbDeviceDialog::SystemCancelledError
       
   198     Operation was cancelled by device dialog framework.
       
   199 */
       
   200 
       
   201 /*!
       
   202     \enum HbDeviceDialog::DeviceDialogFlags
       
   203     Defines construct flags.
       
   204 */
       
   205 /*!
       
   206     \var HbDeviceDialog::DeviceDialogFlags HbDeviceDialog::NoDeviceDialogFlags
       
   207     No flags specified.
       
   208 */
       
   209 /*!
       
   210     \var HbDeviceDialog::DeviceDialogFlags HbDeviceDialog::NoFlags
       
   211     No flags specified.
       
   212 */
       
   213 /*!
       
   214     \var HbDeviceDialog::DeviceDialogFlags HbDeviceDialog::ImmediateResourceReservationFlag
       
   215     Reserves resources immediately instead of delaying until show() is called.
       
   216 */
       
   217 
       
   218 /*!
       
   219      \fn void HbDeviceDialog::dataReceived(QVariantMap data)
       
   220 
       
   221       This signal is emitted when data is received from a device dialog. \a data contains data from
       
   222       the dialog. The structure and meaning of the data is a contract between the dialog and
       
   223       a client. Suggested usage is a set of signal names and parameters.
       
   224 */
       
   225 
       
   226 /*!
       
   227     \fn void HbDeviceDialog::deviceDialogClosed()
       
   228 
       
   229     This signal is emitted when a device dialog is closed. Any data sent by the dialog is indicated by
       
   230     the dataReceived() signal. If the signal is not connected, latest data received is saved and
       
   231     can be retrieved by a receivedData() function.
       
   232 
       
   233     \sa dataReceived() receivedData()
       
   234 */
       
   235 
       
   236 /*!
       
   237     \fn void HbDeviceDialog::error(int error)
       
   238 
       
   239     This signal is emitted when an error has occurred. \a error contains an error code.
       
   240 */
       
   241 
       
   242 #include "hbdevicedialog.h"
       
   243 
       
   244 #include <QtGlobal>
       
   245 
       
   246 // Device dialogs are implemented only for Symbian/S60 OS. All others use a stub which shows
       
   247 // device dialogs in the calling process.
       
   248 #if defined(Q_OS_SYMBIAN)
       
   249 #include "hbdevicedialogsym_p.h"
       
   250 #else
       
   251 #include "hbdevicedialogwin32_p.h"
       
   252 #endif // defined(Q_OS_SYMBIAN)
       
   253 
       
   254 /*!
       
   255     Constructs an object. \a f contains construct flags. \a parent is a parent pointer.
       
   256     HbDeviceDialog can be allocated into a stack if no signals are to be connected. Device dialog
       
   257     service keeps dialogs launched when the object goes out of scope. If any signals
       
   258     are connected, device dialog service will clean all dialogs launched when the instance is
       
   259     deleted. In this case the object must remain in existence until the dialog widget is
       
   260     dismissed.
       
   261 */
       
   262 HbDeviceDialog::HbDeviceDialog(DeviceDialogFlags f, QObject *parent) :
       
   263     QObject(parent), d_ptr(new HbDeviceDialogPrivate)
       
   264 {
       
   265     Q_D(HbDeviceDialog);
       
   266     d->q_ptr = this;
       
   267     d->init(f);
       
   268 }
       
   269 
       
   270 HbDeviceDialog::HbDeviceDialog(HbDeviceDialogPrivate &dd, DeviceDialogFlags f, QObject *parent) :
       
   271     QObject(parent), d_ptr(&dd)
       
   272 {
       
   273     Q_D(HbDeviceDialog);
       
   274     d->q_ptr = this;
       
   275     d->init(f);
       
   276 }
       
   277 
       
   278 HbDeviceDialog::~HbDeviceDialog()
       
   279 {
       
   280     delete d_ptr;
       
   281 }
       
   282 
       
   283 /*!
       
   284     Shows a device dialog using a device dialog service. The function returns immediately after the
       
   285     service has accepted the dialog. Returns true if dialog was accepted, false if error occurred.
       
   286     The service decides when the dialog is actually displayed.
       
   287 
       
   288     \arg deviceDialogType identifies a device dialog to be displayed by a name.
       
   289     \arg parameters defines properties of the dialog.
       
   290 
       
   291     \sa update(), waitForClosed(), cancel()
       
   292 
       
   293     \code
       
   294     // Below code launches a device dialog and continues execution.
       
   295 
       
   296     HbDeviceDialog deviceDialog;
       
   297     QVariantMap parameters;
       
   298     parameters.insertMulti(QString("text"), QVariant(QString("Warning text")));
       
   299     const char *deviceDialogType = "hb.devdlg.examplemessagebox/1.0";
       
   300     deviceDialog.show(QString(deviceDialogType), parameters);
       
   301     \endcode
       
   302 
       
   303     \code
       
   304     // Below code has HbDeviceDialog as a member variable. It connects signals and launches a device dialog.
       
   305 
       
   306     connect(mDeviceDialog, SIGNAL(dataReceived(QVariantMap)),
       
   307         this, SLOT(dataReceived(QVariantMap)));
       
   308     connect(mDeviceDialog, SIGNAL(deviceDialogClosed()), this, SLOT(deviceDialogClosed()));
       
   309     connect(mDeviceDialog, SIGNAL(error(int)), this, SLOT(error(int)));
       
   310     QVariantMap parameters;
       
   311     mDeviceDialog.show(QString("hb.devdlg.examplequery/1.0"), parameters);
       
   312     \endcode
       
   313 */
       
   314 bool HbDeviceDialog::show(const QString &deviceDialogType, const QVariantMap &parameters)
       
   315 {
       
   316     return d_func()->show(deviceDialogType, parameters);
       
   317 }
       
   318 
       
   319 /*!
       
   320     Updates device dialog parameters by a set of new values. show() must be called before an
       
   321     update() can be called. If multiple dialogs have been launched by a single HbDeviceDialog
       
   322     instance, the last dialog launched receives the update. Returns true on success and false
       
   323     if error occurred.
       
   324 
       
   325     \sa show()
       
   326 */
       
   327 bool HbDeviceDialog::update(const QVariantMap &parameters)
       
   328 {
       
   329     return d_func()->update(parameters);
       
   330 }
       
   331 
       
   332 /*!
       
   333     Waits for a device dialog to be displayed and dismissed. \a flags specifies flags passed to
       
   334     QEventLoop::exec() function. Returns true on success and false if error occurred.
       
   335 
       
   336     The wait is implemented by starting a new event loop. Consider following caveats before using
       
   337     this function. Stack usage increases. Depending on application program flow, several event
       
   338     loops may get instantiated on top of each other. Application event processing continues while
       
   339     waitForClosed() executes. When it returns application state may have changed. For example some
       
   340     objects may have been deleted or application may have exited.
       
   341 
       
   342     <b>Note that starting an event loop isn't compatible with gestures.</b> Therefore if an application
       
   343     has an user interface, please don't use this function. Instead connect to signals.
       
   344 
       
   345     \sa cancel()
       
   346 
       
   347     \code
       
   348     // Below code launches a query and then waits for it to close.
       
   349 
       
   350     // Launch query
       
   351     HbDeviceDialog deviceDialog;
       
   352     QVariantMap parameters;
       
   353     deviceDialog.show(QString("hb.devdlg.samplequery/1.0"), parameters);
       
   354     // Wait for note to close
       
   355     deviceDialog.waitForClosed();
       
   356     // Get data the dialog sent
       
   357     QVariantMap data = deviceDialog.receivedData();
       
   358     \endcode
       
   359 */
       
   360 bool HbDeviceDialog::waitForClosed(QEventLoop::ProcessEventsFlag flags)
       
   361 {
       
   362     return d_func()->waitForClosed(flags);
       
   363 }
       
   364 
       
   365 /*!
       
   366     Returns the latest data received from a device dialog. This function can be called instead of
       
   367     connecting to dataReceived() signal. If dataReceived() signal has connections, latest data is
       
   368     not saved and this function returns empty data structure.
       
   369 
       
   370     \sa waitForClosed()
       
   371 */
       
   372 QVariantMap HbDeviceDialog::receivedData() const
       
   373 {
       
   374     return d_func()->receivedData();
       
   375 }
       
   376 
       
   377 /*!
       
   378     Returns a last error. Last error is cleared when any other API function than error() is called.
       
   379 */
       
   380 int HbDeviceDialog::error() const
       
   381 {
       
   382     return d_func()->error();
       
   383 }
       
   384 
       
   385 /*!
       
   386     Cancels a device dialog. The dialog is removed from the device dialog service. Does nothing if
       
   387     the dialog has already been dismissed. Removes dialog if it's waiting to be displayed or
       
   388     currently on display. If multiple dialogs have been launched by a single HbDeviceDialog
       
   389     instance, the last dialog launched is cancelled. deviceDialogClosed() signal is emitted if
       
   390     a dialog was closed. Returns true on success and false if error occurred.
       
   391 
       
   392     \sa show(), deviceDialogClosed()
       
   393 */
       
   394 bool HbDeviceDialog::cancel()
       
   395 {
       
   396     return d_func()->cancel();
       
   397 }