|
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 ¶meters) |
|
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 ¶meters) |
|
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 } |