diff -r 000000000000 -r 16d8024aca5e src/hbwidgets/devicedialogs/hbdeviceprogressdialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hbwidgets/devicedialogs/hbdeviceprogressdialog.cpp Mon Apr 19 14:02:13 2010 +0300 @@ -0,0 +1,838 @@ +/**************************************************************************** +** +** 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 HbWidgets 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 +#include +#include "hbdeviceprogressdialog.h" +#include "hbdeviceprogressdialog_p.h" + +#include +#include + +HbDeviceProgressDialogPrivate::HbDeviceProgressDialogPrivate() : QObject(), + mVisible(false), + mUpdateTimerId(0) +{ + TRACE_ENTRY + for(int i = 0; i < NumActions; i++) { + mDefaultActions[i] = 0; + } + TRACE_EXIT +} + +HbDeviceProgressDialogPrivate::~HbDeviceProgressDialogPrivate() +{ + TRACE_ENTRY + cancel(); + killTimer(mUpdateTimerId); + for(int i = 0; i < NumActions; i++) { + delete mDefaultActions[i]; + } + TRACE_EXIT +} + +void HbDeviceProgressDialogPrivate::initProperties(HbProgressDialog::ProgressDialogType type) +{ + for(int i = 0; i < NumProperties; i++) { + mProperties[i].mFlags = NoFlags; + } + clearActions(); + if (!mDefaultActions[CancelButton]) { + mDefaultActions[CancelButton] = new QAction(0); + } + mActions[CancelButton].mAction = mDefaultActions[CancelButton]; + + QString text; + mProperties[ProgressType].mValue.setValue(static_cast(type)); + mProperties[ProgressType].mFlags = Modified; + if (type == HbProgressDialog::WaitDialog){ + q->setRange(0,0); + q->setAutoClose(false); + } else { + q->setRange(0,100); + q->setAutoClose(true); + } + q->setProgressValue(0); + q->setText(text); + q->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); + q->setIconName(text); + q->setIconAlignment(Qt::AlignCenter); + q->setAnimationDefinition(text); +} + +// Send properties to server +void HbDeviceProgressDialogPrivate::sendToServer(bool show) +{ + killTimer(mUpdateTimerId); + mUpdateTimerId = 0; + + // If this is update but show has not been called, return. + if (!show && !mVisible) { + return; + } + + // If this is update but no properties have been mofified, return + if (!show && !propertiesModified()) { + return; + } + + static const char * const propertyNames[] = { + "progressDialogType", + "maximum", + "minimum", + "value", + "autoClose", + "text", + "textAlignment", + "iconName", + "iconAlignment", + "animationDefinition" + }; + + QVariantMap parameters; + for(int i = 0; i < NumProperties; i++) { + if (mProperties[i].mFlags & Modified) { + if (show || !(mProperties[i].mFlags & SentToServer)) { + parameters.insert(propertyNames[i], mProperties[i].mValue); + mProperties[i].mFlags |= SentToServer; + } + } + } + + static const char * const actionNames[] = { + "primaryActionText" + }; + static const char * const nullActionNames[] = { + "primaryActionNull" + }; + + for(int i = 0; i < NumActions; i++) { + if (mActions[i].mFlags & Modified) { + if (show || !(mActions[i].mFlags & SentToServer)) { + if (mActions[i].mAction) { + parameters.insert(actionNames[i], mActions[i].mAction->text()); + } else { + parameters.insert(nullActionNames[i], true); + } + mActions[i].mFlags |= SentToServer; + } + } + } + + if (show) { + for(int i = 0; i < NumActions; i++) { + mActions[i].mTriggered = false; + } + if (mDeviceDialog.show("com.nokia.hb.deviceprogressdialog/1.0", parameters)) { + mVisible = true; + } else { + // Failed to show the device dialog. Start a one shot to emit aboutToClose() signal. + QTimer::singleShot(0, this, SLOT(aboutToClose())); + } + } else { + mDeviceDialog.update(parameters); + } +} + +// Check if any properties have been modified +bool HbDeviceProgressDialogPrivate::propertiesModified() const +{ + for(int i = 0; i < NumProperties; i++) { + if ((mProperties[i].mFlags & Modified) && !(mProperties[i].mFlags & SentToServer)) { + return true; + } + } + for(int i = 0; i < NumActions; i++) { + if ((mActions[i].mFlags & Modified) && !(mActions[i].mFlags & SentToServer)) { + return true; + } + } + return false; +} + +// Clear actions +void HbDeviceProgressDialogPrivate::clearActions() +{ + for(int i = 0; i < NumActions; i++) { + mActions[i].mAction = 0; + mActions[i].mFlags = NoFlags; + mActions[i].mTriggered = false; + } +} + +// Set int property +void HbDeviceProgressDialogPrivate::setProperty(PropertySelector propertySelector, int value) +{ + Property &property = mProperties[propertySelector]; + property.mValue.setValue(value); + property.mFlags = Modified; + scheduleUpdateEvent(); +} + +// Set string property +void HbDeviceProgressDialogPrivate::setProperty(PropertySelector propertySelector, + const QString &value) +{ + Property &property = mProperties[propertySelector]; + property.mValue.setValue(value); + property.mFlags = Modified; + scheduleUpdateEvent(); +} + +void HbDeviceProgressDialogPrivate::init(HbProgressDialog::ProgressDialogType type) +{ + TRACE_ENTRY + + initProperties(type); + connect(&mDeviceDialog, SIGNAL(deviceDialogClosed()), this, SLOT(aboutToClose())); + connect(&mDeviceDialog, SIGNAL(dataReceived(QVariantMap)), this, SLOT(dataReceived(QVariantMap))); + + TRACE_EXIT +} + +void HbDeviceProgressDialogPrivate::cancel() +{ + TRACE_ENTRY + mDeviceDialog.cancel(); + TRACE_EXIT + return; +} + +// Schedule event to update changed properties to device dialog server. update() is not +// called after each time a property is set. Instead an event is scheduled in order to +// update all changed properties in one shot. +void HbDeviceProgressDialogPrivate::scheduleUpdateEvent() +{ + if (mVisible && mUpdateTimerId == 0) { + mUpdateTimerId = startTimer(0); + } +} + +void HbDeviceProgressDialogPrivate::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == mUpdateTimerId) { + sendToServer(false); + } +} + +HbDeviceProgressDialogPrivate::ActionSelector HbDeviceProgressDialogPrivate::actionSelector( + HbDeviceProgressDialog::ActionRole role) +{ + static const ActionSelector selectors[] = { + CancelButton + }; + const unsigned numSelectors = sizeof(selectors) / sizeof(selectors[0]); + unsigned index = role; + if (index >= numSelectors) { + Q_ASSERT(false); + return InvalidSelector; + } + else { + return selectors[index]; + } +} + +void HbDeviceProgressDialogPrivate::aboutToClose() +{ + TRACE_ENTRY + + mVisible = false; + emit q->aboutToClose(); + + TRACE_EXIT + return; +} + +void HbDeviceProgressDialogPrivate::dataReceived(QVariantMap data) +{ + const char *key = "act"; + QVariantMap::const_iterator i = data.find(key); + if (i != data.constEnd()) { + if (i.value().toString() == "p") { + // Client has pressed button. Signal action if one is set. Otherwise emit + // cancelled() signal. + mActions[CancelButton].mTriggered = true; + QAction *action = mActions[CancelButton].mAction; + if (action) { + action->trigger(); + emit q->cancelled(); + } + } + } +} + +/*! + \class HbDeviceProgressDialog + \brief HbDeviceProgressDialog is a device dialog version of HbProgressDialog. + + It displays a dialog with a wait animation or progress bar, text, icon or animation and a + cancel button. + + Device dialogs are shown on top of any running applications and are always modal by nature. + + Two different dialogs are supported: wait and progress. The wait dialog displays an animated + bar and progress dialog a progress bar indicating progress of the operation. + + Wait dialog is used when length of an operation cannot be determined beforehand. It displays + an animated bar to indicate an action. The dialog is closed by the user pressing the cancel + button, the application closing the dialog after the operation is finished. + + Progress dialog is used when the length of operation can be determined. For example + when deleting a number of files, the progress of the operation could be shown as a + percentage of the files deleted. Application updates the progress bar during the + operation. The dialog closes by user pressing the cancel button, the application closing the + dialog after the operation is finished or automatically when progress value reaches a + maximum. + + HbDeviceProgressDialog provides a similar kind of interface as HbProgressDialog, excluding + functions which handle concrete UI-component related information. Progress dialogs are + always asynchronous by as the client needs to perform the operation and update the dialog + while the dialog is showing. + + Device progress dialog is launched when show() is called. Launched dialog can be updated by setters. + Because updating a dialog requires interprocess communication, it's advisable to fully construct the + progress dialog before calling show(). + + Supported icon animation formats are following: + - GIF (.gif) + - MNG (.mng) + - Frame animations + + Sample code: + + An example showing the wait dialog: + + \code + mDialog = new HbDeviceProgressDialog(HbProgressDialog::WaitDialog); + mDialog->setText("Connecting..."); + mDialog->show(); + \endcode + + An example showing the progress dialog: + + \include deviceprogressdialog/main.cpp + + Creating a frame animation. + + Create an animation definition file: + \code + + + c:\icon1.svg + c:\icon2.svg + c:\icon3.svg + + + \endcode + + Create HbDeviceMessageBox in a way described before and + set definition file and animation's logical name. + + \code + QString animationDefinitionXML("c:\animation.axml"); + QString logicalIconName("frame_anim_looping"); + + msg->setAnimationDefinition(animationDefinitionXML); + msg->setIconName(logicalIconName); + msg->show(); + \endcode + + \sa HbProgressDialog, HbDialog, HbDeviceDialog + \alpha + \hbwidgets +*/ + +/*! + \fn void HbDeviceProgressDialog::aboutToClose(); + + This signal is emitted when a device progress dialog has closed. The closing may + be a result of close() being called, a dialog with autoClose property has reached + its maximum value or user pressing cancel button. It is not emitted if close() is + called before show(). + */ + +/*! + \fn void HbDeviceProgressDialog::cancelled(); + + This signal is emitted when the device progress dialog is closed by user pressing the + "cancel" button. It is not emitted if dialog is closed for any other reason. + */ + +/*! + \enum HbDeviceProgressDialog::ActionRole + Defines roles for actions set into a progress dialog. +*/ +/*! + \var HbDeviceProgressDialog::ActionRole HbDeviceProgressDialog::InvalidRole + No action. +*/ +/*! + \var HbDeviceProgressDialog::ActionRole HbDeviceProgressDialog::CancelButtonRole + Cancel button action. +*/ + +/*! + Constructor. + \param type Must be one of the defined HbProgressDialog::ProgressDialogType enumerations. + \param parent An optional parameter. +*/ +HbDeviceProgressDialog::HbDeviceProgressDialog(HbProgressDialog::ProgressDialogType type, QObject *parent) : + QObject(parent), d(new HbDeviceProgressDialogPrivate) +{ + TRACE_ENTRY + d->q = this; + d->init(type); + TRACE_EXIT +} + +/*! + Constructor. + \param parent An optional parameter. +*/ +HbDeviceProgressDialog::HbDeviceProgressDialog(QObject *parent) : + QObject(parent), d(new HbDeviceProgressDialogPrivate) +{ + TRACE_ENTRY + d->q = this; + d->init(HbProgressDialog::ProgressDialog); + TRACE_EXIT +} + +/*! + Destructs the class. +*/ +HbDeviceProgressDialog::~HbDeviceProgressDialog() +{ + TRACE_ENTRY + delete d; + TRACE_EXIT +} + +/*! + Executes the dialog asynchronously. +*/ +void HbDeviceProgressDialog::show() +{ + TRACE_ENTRY + d->sendToServer(true); + TRACE_EXIT + } + +/*! + Updates changed properties of a launched progress dialog to device dialog service using + interprocess communication. Has no effect if show() has not been called or dialog has + closed already. Calling show() is optional as updating any property schedules an event + and the dialog is updated next time Qt event loop executes. + + \sa show() +*/ +void HbDeviceProgressDialog::update() +{ + TRACE_ENTRY + d->sendToServer(false); + TRACE_EXIT +} + +/*! + Closes the dialog. + + \deprecated HbDeviceProgressDialog::cancel() + is deprecated. Replaced by HbDeviceProgressDialog::close(). + +*/ +void HbDeviceProgressDialog::cancel() +{ + TRACE_ENTRY + return d->cancel(); + TRACE_EXIT +} + +/*! + Closes the dialog. +*/ +void HbDeviceProgressDialog::close() +{ + TRACE_ENTRY + return d->cancel(); + TRACE_EXIT +} + +/*! + Returns an action user triggered causing the dialog to close. Returns 0 if none of the actions were + triggered and dialog was closed for other reason. + + \sa show(), action() +*/ +const QAction *HbDeviceProgressDialog::triggeredAction() const +{ + for(int i = 0; i < HbDeviceProgressDialogPrivate::NumActions; i++) { + if (d->mActions[i].mTriggered) { + return d->mActions[i].mAction; + } + } + return 0; +} + +/*! + Sets the maximum value of the progress bar within the dialog. + + \sa maximum() +*/ +void HbDeviceProgressDialog::setMaximum(int max) +{ + TRACE_ENTRY + // Don't allow wait dialog to set max/min other than zero as wait + // animation bar doesn't work in that case. + if (progressType() == HbProgressDialog::WaitDialog) { + max = 0; + } + d->setProperty(HbDeviceProgressDialogPrivate::Maximum, max); + TRACE_EXIT +} + +/*! + Returns the maximum value of the progress bar within the dialog. Default value is 100. + + \sa setMaximum() +*/ +int HbDeviceProgressDialog::maximum() const +{ + return d->mProperties[HbDeviceProgressDialogPrivate::Maximum].mValue.toInt(); +} + +/*! + Sets the minimum value of the progress bar within the dialog. + + \sa minimum() +*/ +void HbDeviceProgressDialog::setMinimum(int min) +{ + TRACE_ENTRY + // Don't allow wait dialog to set max/min other than zero as wait + // animation bar doesn't work in that case. + if (progressType() == HbProgressDialog::WaitDialog) { + min = 0; + } + d->setProperty(HbDeviceProgressDialogPrivate::Minimum, min); + TRACE_EXIT +} + +/*! + Returns the minimum value of the progress bar within the dialog. Default value is 0. + + \sa setMinimum() +*/ +int HbDeviceProgressDialog::minimum() const +{ + return d->mProperties[HbDeviceProgressDialogPrivate::Minimum].mValue.toInt(); +} + +/*! + Sets the minimum and maximum value of the progress bar within the dialog. + + \sa minimum(), maximum() +*/ +void HbDeviceProgressDialog::setRange(int min, int max) +{ + setMinimum(min); + setMaximum(max); +} + +/*! + Sets the value of the progress bar within the dialog. + + \sa progressValue() +*/ +void HbDeviceProgressDialog::setProgressValue(int progressValue) +{ + TRACE_ENTRY + d->setProperty(HbDeviceProgressDialogPrivate::Value, progressValue); + TRACE_EXIT +} + +/*! + Returns the value of the progress bar within the dialog. + + \sa setProgressValue() + */ +int HbDeviceProgressDialog::progressValue() const +{ + return d->mProperties[HbDeviceProgressDialogPrivate::Value].mValue.toInt(); +} + +/*! + Sets the autoClose property value of the dialog. + + \param autoClose When set, the dialog is closed when value of the progress bar reaches + the maximum value of the progress bar. + + \sa autoClose() +*/ +void HbDeviceProgressDialog::setAutoClose(bool autoClose) +{ + TRACE_ENTRY + d->setProperty(HbDeviceProgressDialogPrivate::AutoClose, autoClose); + TRACE_EXIT +} + +/*! + Returns the value of the autoClose property of the dialog. + + The default value is true for HbProgressDialog::ProgressDialog and false + for HbProgressDialog::WaitDialog. + + \sa setAutoClose() + */ +bool HbDeviceProgressDialog::autoClose() const +{ + return d->mProperties[HbDeviceProgressDialogPrivate::AutoClose].mValue.toInt(); +} + +/*! + Sets dialog's progress type. After setProgressType(), a new dialog is launched by a show(). + + \sa progressType() +*/ +void HbDeviceProgressDialog::setProgressType(HbProgressDialog::ProgressDialogType type) +{ + TRACE_ENTRY + // After setProgressType(), a new dialog is launched by a show() + d->mVisible = false; + // All properties initialized to default + d->initProperties(type); + TRACE_EXIT +} + +/*! + Returns dialog's progress type. + + \sa setProgressType() +*/ +HbProgressDialog::ProgressDialogType HbDeviceProgressDialog::progressType() const +{ + return static_cast + (d->mProperties[HbDeviceProgressDialogPrivate::ProgressType].mValue.toInt()); +} + +/*! + Sets text of the dialog. + + \sa text() +*/ +void HbDeviceProgressDialog::setText(const QString &text) +{ + TRACE_ENTRY + d->setProperty(HbDeviceProgressDialogPrivate::Text, text); + TRACE_EXIT +} + +/*! + Returns text of the dialog. + \sa setText() +*/ +QString HbDeviceProgressDialog::text() const +{ + return d->mProperties[HbDeviceProgressDialogPrivate::Text].mValue.toString(); +} + +/*! + Sets the text alignment. + + \param align Qt defined alignment options can used. + + \sa textAlignment() +*/ +void HbDeviceProgressDialog::setTextAlignment(Qt::Alignment align) +{ + TRACE_ENTRY + d->setProperty(HbDeviceProgressDialogPrivate::TextAlignment, align); + TRACE_EXIT +} + +/*! + Returns the text alignment. + + The default value is Qt::AlignLeft|Qt::AlignVCenter + + \sa setTextAlignment() +*/ +Qt::Alignment HbDeviceProgressDialog::textAlignment() const +{ + return static_cast + (d->mProperties[HbDeviceProgressDialogPrivate::TextAlignment].mValue.toInt()); +} + +/*! + Sets the text wrapping. + + \param wrap When set, the text is drawn with Qt::TextWordWrap enabled meaning that + lines breaks are at appropriate point, e.g. at word boundaries. + + \sa textWrapping() + + \deprecated HbDeviceProgressDialog::setTextWrapping() + is deprecated. Will be removed. +*/ +void HbDeviceProgressDialog::setTextWrapping(bool wrap) +{ + TRACE_ENTRY + Q_UNUSED(wrap) + TRACE_EXIT +} + +/*! + Returns the text wrapping setting. Default value is true. + + \sa setTextWrapping() + + \deprecated HbDeviceProgressDialog::textWrapping() + is deprecated. Will be removed. +*/ +bool HbDeviceProgressDialog::textWrapping() const +{ + return true; +} + +/*! + Sets message box icon name or animation logical name. + + \param aIconName Icon name. Icon can be from Hb resources or themes. Or can be a file in + a file system. + + \sa IconName() +*/ +void HbDeviceProgressDialog::setIconName(const QString &iconName) +{ + TRACE_ENTRY + d->setProperty(HbDeviceProgressDialogPrivate::IconName, iconName); + TRACE_EXIT +} + +/*! + Returns name and path of the icon or animation's logical name. + + \sa setIconName() +*/ +QString HbDeviceProgressDialog::iconName() const +{ + return d->mProperties[HbDeviceProgressDialogPrivate::IconName].mValue.toString(); +} + +/*! + Sets the icon alignment. + + \param align Qt defined alignment options can used. + + \sa iconAlignment() +*/ +void HbDeviceProgressDialog::setIconAlignment(Qt::Alignment align) +{ + TRACE_ENTRY + d->setProperty(HbDeviceProgressDialogPrivate::IconAlignment, align); + TRACE_EXIT +} + +/*! + Returns the icon alignment. Default value is Qt::AlignCenter. + + \sa setIconAlignment() +*/ +Qt::Alignment HbDeviceProgressDialog::iconAlignment() const +{ + return static_cast + (d->mProperties[HbDeviceProgressDialogPrivate::IconAlignment].mValue.toInt()); +} + +/*! + Sets animation definition to a dialog. Animation's logical name has to be set + using setIcon(). Animation definition files must be stored to a place where they + can be accessed by device dialog service. + + Supported animation formats are following: + - GIF (.gif) + - MNG (.mng) + - Frame animations + + \param animationDefinition Path and name of the animation definition file. + + \sa setIcon(), animationDefinition(), HbIconAnimationManager::addDefinitionFile() + +*/ +void HbDeviceProgressDialog::setAnimationDefinition(QString &animationDefinition) +{ + TRACE_ENTRY + d->setProperty(HbDeviceProgressDialogPrivate::AnimationDefinition, animationDefinition); + TRACE_EXIT +} + +/*! + Returns animation definition file name. + + \sa setAnimationDefinition() +*/ +QString HbDeviceProgressDialog::animationDefinition() const +{ + return d->mProperties[HbDeviceProgressDialogPrivate::AnimationDefinition].mValue.toString(); +} + +/*! + Sets a new action into progress dialog. When users presses a button on dialog, triggered() + signal of the action is emitted. HbDeviceProgressDialog constructor sets a default action + into a dialog. + + \param action Action or Null. Ownership is not transferred. + \param role Selects an action to set. + + \sa action() +*/ +void HbDeviceProgressDialog::setAction(QAction *action, ActionRole role) +{ + TRACE_ENTRY + HbDeviceProgressDialogPrivate::ActionSelector actionSelector = + HbDeviceProgressDialogPrivate::actionSelector(role); + if (actionSelector != HbDeviceProgressDialogPrivate::InvalidSelector) { + HbDeviceProgressDialogPrivate::Action &dialogAction = d->mActions[actionSelector]; + dialogAction.mAction = action; + dialogAction.mFlags = HbDeviceProgressDialogPrivate::Modified; + d->scheduleUpdateEvent(); + } + TRACE_EXIT +} + +/*! + Returns progress dialog action. The action may be a default action owned by the dialog + or the one set by setAction(). + + \param role Selects an action to get. + + \sa setAction() +*/ +QAction *HbDeviceProgressDialog::action(ActionRole role) const +{ + HbDeviceProgressDialogPrivate::ActionSelector actionSelector = + HbDeviceProgressDialogPrivate::actionSelector(role); + return actionSelector != HbDeviceProgressDialogPrivate::InvalidSelector ? + d->mActions[actionSelector].mAction : 0; +}