diff options
Diffstat (limited to 'gui')
-rw-r--r-- | gui/CMakeLists.txt | 26 | ||||
-rw-r--r-- | gui/polkitqt1-gui-action.cpp | 515 | ||||
-rw-r--r-- | gui/polkitqt1-gui-action.h | 304 | ||||
-rw-r--r-- | gui/polkitqt1-gui-actionbutton.cpp | 166 | ||||
-rw-r--r-- | gui/polkitqt1-gui-actionbutton.h | 145 | ||||
-rw-r--r-- | gui/polkitqt1-gui-actionbutton_p.h | 50 | ||||
-rw-r--r-- | gui/polkitqt1-gui-actionbuttons.cpp | 73 | ||||
-rw-r--r-- | gui/polkitqt1-gui-actionbuttons.h | 114 | ||||
-rw-r--r-- | gui/polkitqt1-gui-actionbuttons_p.h | 36 |
9 files changed, 1429 insertions, 0 deletions
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt new file mode 100644 index 000000000..44abb7582 --- /dev/null +++ b/gui/CMakeLists.txt @@ -0,0 +1,26 @@ +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set(polkit_qt_gui_SRCS + polkitqt1-gui-action.cpp + polkitqt1-gui-actionbutton.cpp + polkitqt1-gui-actionbuttons.cpp +) + +automoc4_add_library(polkit-qt-gui-1 SHARED ${polkit_qt_gui_SRCS}) + +target_link_libraries(polkit-qt-gui-1 + ${QT_QTCORE_LIBRARY} + ${QT_QTGUI_LIBRARY} + ${QT_QTDBUS_LIBRARY} + ${POLKIT_LIBRARIES} + polkit-qt-core-1 +) + +set_target_properties(polkit-qt-gui-1 PROPERTIES VERSION ${POLKITQT-1_LIBRARY_VERSION} + SOVERSION ${POLKITQT-1_ABI_VERSION} + DEFINE_SYMBOL MAKE_POLKITQT1_LIB) + +install(TARGETS polkit-qt-gui-1 ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/gui/polkitqt1-gui-action.cpp b/gui/polkitqt1-gui-action.cpp new file mode 100644 index 000000000..82083d134 --- /dev/null +++ b/gui/polkitqt1-gui-action.cpp @@ -0,0 +1,515 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Daniel Nicoletti <[email protected]> + * Copyright (C) 2009 Dario Freddi <[email protected]> + * Copyright (C) 2009 Jaroslav Reznik <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "polkitqt1-gui-action.h" +#include "polkitqt1-authority.h" +#include "polkitqt1-subject.h" + +#include <QtCore/QCoreApplication> + +namespace PolkitQt1 +{ + +namespace Gui +{ + +/** + * \internal + */ +class Action::Private +{ +public: + Private(Action *p); + + Action *parent; + + QString actionId; + Authority::Result pkResult; + qint64 targetPID; + + void updateAction(); + bool computePkResult(); + void configChanged(); + + bool initiallyChecked; + + // states data + bool selfBlockedVisible; + bool selfBlockedEnabled; + QString selfBlockedText; + QString selfBlockedWhatsThis; + QString selfBlockedToolTip; + QIcon selfBlockedIcon; + + bool noVisible; + bool noEnabled; + QString noText; + QString noWhatsThis; + QString noToolTip; + QIcon noIcon; + + bool authVisible; + bool authEnabled; + QString authText; + QString authWhatsThis; + QString authToolTip; + QIcon authIcon; + + bool yesVisible; + bool yesEnabled; + QString yesText; + QString yesWhatsThis; + QString yesToolTip; + QIcon yesIcon; +}; + +Action::Private::Private(Action *p) + : parent(p) + , targetPID(getpid()) +{ + initiallyChecked = false; + + // Set the default values + selfBlockedVisible = true; + selfBlockedEnabled = false; + + noVisible = true; + noEnabled = false; + + authVisible = true; + authEnabled = true; + + yesVisible = true; + yesEnabled = true; +} + +Action::Action(const QString &actionId, QObject *parent) + : QAction(parent) + , d(new Private(this)) +{ + // this must be called AFTER the values initialization + setPolkitAction(actionId); + + // track the config changes to update the action + connect(Authority::instance(), SIGNAL(configChanged()), + this, SLOT(configChanged())); + // for now we call config changed.. + connect(Authority::instance(), SIGNAL(consoleKitDBChanged()), + this, SLOT(configChanged())); +} + +Action::~Action() +{ + delete d; +} + +bool Action::activate() +{ + switch (d->pkResult) { + case Authority::Yes: + case Authority::Challenge: + // just Q_EMIT the 'activated' signal + Q_EMIT authorized(); + return true; + break; + default: + case Authority::No: + if (d->noEnabled) { + /* If PolicyKit says no... and we got here.. it means + * that the user set the property "no-enabled" to + * TRUE.. + * + * Hence, they probably have a good reason for doing + * this so do let the 'activate' signal propagate.. + */ + Q_EMIT authorized(); + return true; + } + break; + } + return false; +} + +void Action::setChecked(bool checked) +{ + // We store this as initiallyChecked + // to be able to undo changes in case the auth fails + d->initiallyChecked = checked; + QAction::setChecked(checked); +} + +void Action::Private::updateAction() +{ + if (Authority::instance()->hasError()) { + return; + } + + switch (pkResult) { + default: + case Authority::Unknown: + case Authority::No: + qobject_cast<QAction *>(parent)->setVisible(noVisible); + qobject_cast<QAction *>(parent)->setEnabled(noEnabled); + qobject_cast<QAction *>(parent)->setText(noText); + if (!noWhatsThis.isNull()) { + qobject_cast<QAction *>(parent)->setWhatsThis(noWhatsThis); + } + if (!noToolTip.isNull()) { + qobject_cast<QAction *>(parent)->setToolTip(noToolTip); + } + qobject_cast<QAction *>(parent)->setIcon(noIcon); + break; + + case Authority::Challenge: + qobject_cast<QAction *>(parent)->setVisible(authVisible); + qobject_cast<QAction *>(parent)->setEnabled(authEnabled); + qobject_cast<QAction *>(parent)->setText(authText); + if (!authWhatsThis.isNull()) { + qobject_cast<QAction *>(parent)->setWhatsThis(authWhatsThis); + } + if (!authToolTip.isNull()) { + qobject_cast<QAction *>(parent)->setToolTip(authToolTip); + } + qobject_cast<QAction *>(parent)->setIcon(authIcon); + break; + case Authority::Yes: + qobject_cast<QAction *>(parent)->setVisible(yesVisible); + qobject_cast<QAction *>(parent)->setEnabled(yesEnabled); + qobject_cast<QAction *>(parent)->setText(yesText); + if (!yesWhatsThis.isNull()) { + qobject_cast<QAction *>(parent)->setWhatsThis(yesWhatsThis); + } + if (!yesToolTip.isNull()) { + qobject_cast<QAction *>(parent)->setToolTip(yesToolTip); + } + qobject_cast<QAction *>(parent)->setIcon(yesIcon); + if (parent->isCheckable()) { + qobject_cast<QAction *>(parent)->setChecked(!initiallyChecked); + } + break; + } + Q_EMIT parent->dataChanged(); +} + +void Action::Private::configChanged() +{ + bool result_changed; + result_changed = computePkResult(); + if (result_changed) { + updateAction(); + } +} + +bool Action::Private::computePkResult() +{ + Authority::Result old_result; + UnixProcessSubject subject(parent->targetPID()); + + old_result = pkResult; + pkResult = Authority::Unknown; + + pkResult = Authority::instance()->checkAuthorizationSync(actionId, subject, Authority::None); + + return old_result != pkResult; +} + +qint64 Action::targetPID() const +{ + if (d->targetPID != 0) { + return d->targetPID; + } else { + return QCoreApplication::applicationPid(); + } +} + +void Action::setTargetPID(qint64 pid) +{ + d->targetPID = pid; + + d->computePkResult(); + d->updateAction(); +} + +bool Action::isAllowed() const +{ + return d->pkResult == Authority::Yes; +} + +bool Action::is(const QString &other) const +{ + return d->actionId == other; +} + +void Action::revoke() +{ + /*TODO: implement it? no negative authorizations available, no authorization db*/ +} + +void Action::setText(const QString &text, States states) +{ + if (states & All) { + d->selfBlockedText = text; + d->noText = text; + d->authText = text; + d->yesText = text; + } else if (states & Auth) { + d->authText = text; + } else if (states & No) { + d->noText = text; + } else if (states & SelfBlocked) { + d->selfBlockedText = text; + } else if (states & Yes) { + d->yesText = text; + } + + d->updateAction(); +} + +QString Action::text(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesText; + case No: + return d->noText; + case Auth: + return d->authText; + case SelfBlocked: + return d->selfBlockedText; + case None: + return QAction::text(); + default: + return QString(); + } +} + +void Action::setToolTip(const QString &toolTip, States states) +{ + if (states & All) { + d->selfBlockedToolTip = toolTip; + d->noToolTip = toolTip; + d->authToolTip = toolTip; + d->yesToolTip = toolTip; + } else if (states & Auth) { + d->authToolTip = toolTip; + } else if (states & No) { + d->noToolTip = toolTip; + } else if (states & SelfBlocked) { + d->selfBlockedToolTip = toolTip; + } else if (states & Yes) { + d->yesToolTip = toolTip; + } + + d->updateAction(); +} + +QString Action::toolTip(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesToolTip; + case No: + return d->noToolTip; + case Auth: + return d->authToolTip; + case SelfBlocked: + return d->selfBlockedToolTip; + case None: + return QAction::toolTip(); + default: + return QString(); + } +} + +void Action::setWhatsThis(const QString &whatsThis, States states) +{ + if (states & All) { + d->selfBlockedWhatsThis = whatsThis; + d->noWhatsThis = whatsThis; + d->authWhatsThis = whatsThis; + d->yesWhatsThis = whatsThis; + } else if (states & Auth) { + d->authWhatsThis = whatsThis; + } else if (states & No) { + d->noWhatsThis = whatsThis; + } else if (states & SelfBlocked) { + d->selfBlockedWhatsThis = whatsThis; + } else if (states & Yes) { + d->yesWhatsThis = whatsThis; + } + + d->updateAction(); +} + +QString Action::whatsThis(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesWhatsThis; + case No: + return d->noWhatsThis; + case Auth: + return d->authWhatsThis; + case SelfBlocked: + return d->selfBlockedWhatsThis; + case None: + return QAction::whatsThis(); + default: + return QString(); + } +} + +void Action::setIcon(const QIcon &icon, States states) +{ + if (states & All) { + d->selfBlockedIcon = icon; + d->noIcon = icon; + d->authIcon = icon; + d->yesIcon = icon; + } else if (states & Auth) { + d->authIcon = icon; + } else if (states & No) { + d->noIcon = icon; + } else if (states & SelfBlocked) { + d->selfBlockedIcon = icon; + } else if (states & Yes) { + d->yesIcon = icon; + } + + d->updateAction(); +} + +QIcon Action::icon(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesIcon; + case No: + return d->noIcon; + case Auth: + return d->authIcon; + case SelfBlocked: + return d->selfBlockedIcon; + case None: + return QAction::icon(); + default: + return QIcon(); + } +} + +void Action::setEnabled(bool enabled, States states) +{ + if (states & All) { + d->selfBlockedEnabled = enabled; + d->noEnabled = enabled; + d->authEnabled = enabled; + d->yesEnabled = enabled; + } else if (states & Auth) { + d->authEnabled = enabled; + } else if (states & No) { + d->noEnabled = enabled; + } else if (states & SelfBlocked) { + d->selfBlockedEnabled = enabled; + } else if (states & Yes) { + d->yesEnabled = enabled; + } + + d->updateAction(); +} + +bool Action::isEnabled(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesEnabled; + case No: + return d->noEnabled; + case Auth: + return d->authEnabled; + case SelfBlocked: + return d->selfBlockedEnabled; + case None: + return QAction::isEnabled(); + default: + return false; + } +} + +void Action::setVisible(bool visible, States states) +{ + if (states & All) { + d->selfBlockedVisible = visible; + d->noVisible = visible; + d->authVisible = visible; + d->yesVisible = visible; + } else if (states & Auth) { + d->authVisible = visible; + } else if (states & No) { + d->noVisible = visible; + } else if (states & SelfBlocked) { + d->selfBlockedVisible = visible; + } else if (states & Yes) { + d->yesVisible = visible; + } + + d->updateAction(); +} + +bool Action::isVisible(Action::State state) const +{ + switch (state) { + case Yes: + return d->yesVisible; + case No: + return d->noVisible; + case Auth: + return d->authVisible; + case SelfBlocked: + return d->selfBlockedVisible; + case None: + return QAction::isVisible(); + default: + return false; + } +} + +void Action::setPolkitAction(const QString &actionId) +{ + //TODO: + d->actionId = actionId; + + d->computePkResult(); + d->updateAction(); +} + +//-------------------------------------------------- + +QString Action::actionId() const +{ + return d->actionId; +} + +} + +} + +#include "polkitqt1-gui-action.moc" diff --git a/gui/polkitqt1-gui-action.h b/gui/polkitqt1-gui-action.h new file mode 100644 index 000000000..fed4cdc12 --- /dev/null +++ b/gui/polkitqt1-gui-action.h @@ -0,0 +1,304 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Daniel Nicoletti <[email protected]> + * Copyright (C) 2009 Dario Freddi <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef POLKITQT1_GUI_ACTION_H +#define POLKITQT1_GUI_ACTION_H + +#include "polkitqt1-export.h" + +#include <QtGui/QAction> + +namespace PolkitQt1 +{ + +namespace Gui +{ + +/** + * \class Action polkitqt1-gui-action.h Action + * \author Daniel Nicoletti <[email protected]> + * \author Dario Freddi <[email protected]> + * + * \brief Class used to manage actions + * + * This class is an interface around PolicyKit Actions. + * By using this class, you are able to track the result of a + * given action. + * + * Most of the times, you would want to use this class combined + * with a QAbstractButton. In this case, you can use the more + * comfortable ActionButton class that manages button's properties + * update for you. + * + * \see ActionButton + */ +class POLKITQT1_EXPORT Action : public QAction +{ + Q_OBJECT + Q_DISABLE_COPY(Action) +public: + + enum State { + None = 0, + SelfBlocked = 1, + Yes = 2, + No = 4, + Auth = 8, + // Future usage = 16, + // Future usage = 32, + // Future usage = 64, + // Future usage = 128, + // Future usage = 256, + All = 512 + }; + Q_DECLARE_FLAGS(States, State) + + /** + * Constructs a new Action item + * + * \param actionId the PolicyKit action Id (e.g.: org.freedesktop.policykit.read) + * \param parent the object parent + */ + explicit Action(const QString &actionId = QString(), QObject *parent = 0); + ~Action(); + +Q_SIGNALS: + /** + * Emitted when the PolicyKit result (PolKitResult) + * for the given action or the internal data changes + * (i.e. the user called one of the set methods). + * You should connect to this signal if you want + * to track these changes. + */ + void dataChanged(); + + /** + * Emitted when using this class as a proxy + * for a given action, It's only emitted if the + * activate() slot is called and the auth permits + * the action + * + * \see activate() + */ + void authorized(); + +public Q_SLOTS: + /** + * Use this slot if you want to activate + * the action. authorized() will be emitted + * if the action gets authorized. + * + * \return \c true if the caller can do the action + * + * \see authorized() + */ + bool activate(); + + /** + * Defines the checked state. The opposite state will + * trigger authentication for this actions. For example, if + * you set this to \c true, when the action's checked state + * will become \c false, the authentication will be triggered. + * + * \param checked the new checked state + */ + void setChecked(bool checked); + + /** + * This method can be used to revoke the authorization + * obtained for this action. + */ + void revoke(); + +public: + /** + * Changes the action being tracked + * + * \param actionId The new action ID + */ + void setPolkitAction(const QString &actionId); + + /** + * Returns the current action ID. + * + * \return The action ID + * + */ + QString actionId() const; + + /** + * Sets the text for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \param text the new text for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setText(const QString &text, States states = All); + + /** + * Sets the tooltip for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \param toolTip the new tooltip for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setToolTip(const QString &toolTip, States states = All); + + /** + * Sets the whatsthis for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \param whatsThis the new whatsthis for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setWhatsThis(const QString &whatsThis, States states = All); + + /** + * Sets the icon for the current action. This will + * be shown only in the states specified in the \c states parameter. + * \note You need to pass a QIcon here. You can easily + * create one from a Pixmap, or pass a KIcon + * \param icon the new icon for the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setIcon(const QIcon &icon, States states = All); + + /** + * Sets whether the current action is visible or not. This will + * be applied only in the states specified in the \c states parameter. + * \param visible visibility of the action + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setVisible(bool visible, States states = All); + + /** + * Sets whether the current action is enabled or not. This will + * be shown only in the states specified in the \c states parameter. + * \param enabled whether the Action will be enabled or not + * \param states the states of the Polkit action on which the setting + * will be applied + */ + void setEnabled(bool enabled, States states = All); + + /** + * This function sets the process id of the target that + * should receive the authorization. Set this to 0 to set + * the current process as the target. + * + * \param pid The target process id; 0 if it is the current process + */ + void setTargetPID(qint64 pid); + + /** + * Gets the text of the action when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns The text shown when the action is in the specified state + */ + QString text(State state = None) const; + + /** + * Gets the tooltip of the action when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns The tooltip shown when the action is in the specified state + */ + QString toolTip(State state = None) const; + + /** + * Gets the whatsThis of the action when it is in the specified state + * + * \param state The state to be checked + * \returns The whatsThis shown when the action is in the specified state + */ + QString whatsThis(State state = None) const; + + /** + * Gets the icon of the action when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns The icon shown when the action is in the specified state + */ + QIcon icon(State state = None) const; + + /** + * Gets whether the action is visible or not when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns Whether the action is visible or not in the specified state + */ + bool isVisible(State state = None) const; + + /** + * Gets whether the action is enabled or not when it is in the specified state + * + * \note Passing None will return the current value + * \param state The state to be checked + * \returns Whether the action is enabled or not in the specified state + */ + bool isEnabled(State state = None) const; + + /** + * \see setTargetPID + */ + qint64 targetPID() const; + + /** + * This method can be used to check the if the current action + * can be performed (i.e. PolKitResult is YES). + * \note This method does not call the authentication dialog, use + * activate() instead + * \return \c true if the action can be performed + */ + bool isAllowed() const; + + /** + * This method compares a PolicyKit action Id with the + * current one of the object. + * + * \see actionId() + * + * \param actionId the action Id to compare + * + * \return \c true if the actionId is the same as this object's one + */ + bool is(const QString &actionId) const; + +private: + class Private; + Private * const d; + + Q_PRIVATE_SLOT(d, void configChanged()) +}; + +} + +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(PolkitQt1::Gui::Action::States) + +#endif diff --git a/gui/polkitqt1-gui-actionbutton.cpp b/gui/polkitqt1-gui-actionbutton.cpp new file mode 100644 index 000000000..a9963dcb9 --- /dev/null +++ b/gui/polkitqt1-gui-actionbutton.cpp @@ -0,0 +1,166 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Daniel Nicoletti <[email protected]> + * Copyright (C) 2009 Dario Freddi <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "polkitqt1-gui-actionbutton.h" + +#include "polkitqt1-gui-actionbutton_p.h" + +namespace PolkitQt1 +{ + +namespace Gui +{ + +ActionButton::ActionButton(QAbstractButton *button, const QString &actionId, QObject *parent) + : Action(actionId, parent) + , d_ptr(new ActionButtonPrivate(QList<QAbstractButton *>() << button)) +{ + d_ptr->q_ptr = this; + + setButton(button); + connect(this, SIGNAL(dataChanged()), SLOT(updateButton())); +} + +ActionButton::ActionButton(ActionButtonPrivate &dd, const QString &actionId, QObject *parent) + : Action(actionId, parent) + , d_ptr(&dd) +{ + d_ptr->q_ptr = this; + + connect(this, SIGNAL(dataChanged()), SLOT(updateButton())); +} + +ActionButton::~ActionButton() +{ + delete d_ptr; +} + +void ActionButtonPrivate::updateButton() +{ + Q_Q(ActionButton); + + Q_FOREACH(QAbstractButton *ent, buttons) { + ent->setVisible(q->isVisible()); + ent->setEnabled(q->isEnabled()); + ent->setText(q->text()); + if (!q->toolTip().isNull()) { + ent->setToolTip(q->toolTip()); + } + if (!q->whatsThis().isNull()) { + ent->setWhatsThis(q->whatsThis()); + } + ent->setIcon(q->icon()); + // if the item cannot do the action anymore + // lets revert to the initial state + if (ent->isCheckable()) { + ent->setChecked(q->isChecked()); + } + } +} + +bool ActionButton::activate() +{ + Q_D(ActionButton); + + bool tg = false; + Q_FOREACH(QAbstractButton *ent, d->buttons) { + if (ent->isCheckable()) { + // we set the the current Action state + ent->setChecked(isChecked()); + // toggle the action cause we are not directly connected there.. + tg = true; + } + } + + if (tg) { + toggle(); + } + + return Action::activate(); +} + +void ActionButton::setButton(QAbstractButton *button) +{ + Q_D(ActionButton); + + // First, let's clear the list + Q_FOREACH(QAbstractButton *ent, d->buttons) { + d->removeButton(ent); + } + + // And then add it + d->addButton(button); +} + +void ActionButtonPrivate::addButton(QAbstractButton *button) +{ + Q_Q(ActionButton); + + buttons.append(button); + QObject::connect(button, SIGNAL(clicked(bool)), q, SLOT(streamClicked(bool))); + QObject::connect(q, SIGNAL(toggled(bool)), button, SLOT(toggle())); + if (q->isCheckable()) { + // the button should follow our first buttons + button->setCheckable(true); + } else if (button->isCheckable()) { + // if we are not checkable BUT the button + // is (eg a QCheckBox) we should set all buttons to + // checkable. + Q_FOREACH(QAbstractButton *ent, buttons) { + ent->setCheckable(true); + } + // set the checkable state of Action to store the initial state + q->setCheckable(true); + } + // call this after m_activateOnCheck receives the value + updateButton(); +} + +void ActionButtonPrivate::removeButton(QAbstractButton *button) +{ + Q_Q(ActionButton); + + if (buttons.contains(button)) { + QObject::disconnect(button, SIGNAL(clicked(bool)), q, SLOT(streamClicked(bool))); + QObject::disconnect(q, SIGNAL(toggled(bool)), button, SLOT(toggle())); + buttons.removeOne(button); + } +} + +QAbstractButton *ActionButton::button() const +{ + Q_D(const ActionButton); + + return d->buttons.first(); +} + +void ActionButtonPrivate::streamClicked(bool c) +{ + Q_Q(ActionButton); + + Q_EMIT q->clicked(qobject_cast<QAbstractButton *>(q->sender()), c); +} + +} + +} + +#include "polkitqt1-gui-actionbutton.moc" diff --git a/gui/polkitqt1-gui-actionbutton.h b/gui/polkitqt1-gui-actionbutton.h new file mode 100644 index 000000000..23f1783b0 --- /dev/null +++ b/gui/polkitqt1-gui-actionbutton.h @@ -0,0 +1,145 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Daniel Nicoletti <[email protected]> + * Copyright (C) 2009 Dario Freddi <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef POLKITQT1_GUI_ACTIONBUTTON_H +#define POLKITQT1_GUI_ACTIONBUTTON_H + +#include "polkitqt1-export.h" +#include "polkitqt1-gui-action.h" + +class QAbstractButton; + +namespace PolkitQt1 +{ + +namespace Gui +{ + +class ActionButtonPrivate; +/** + * \class ActionButton polkitqt1-gui-actionbutton.h ActionButton + * \author Daniel Nicoletti <[email protected]> + * \author Dario Freddi <[email protected]> + * + * \brief Class used to hold and update a QAbstractButton + * + * This class allows you to associate QAbstractButtons + * (i.e. QPushButton) to a PolicyKit Action. It will update the + * button properties according to the PolicyKit Action automatically. + * + * \note You should connect the activated() signal to receive + * a notification when the user clicked the button and gets + * permission to perform the given action. If you set 'noEnabled' + * to \c true it will be emitted when PolKitResult is NO. + */ +class POLKITQT1_EXPORT ActionButton : public Action +{ + Q_OBJECT + Q_DECLARE_PRIVATE(ActionButton) + Q_DISABLE_COPY(ActionButton) + +public: + /** + * Constructs a new ActionButton. You need to pass this + * constructor an existing QAbstractButton, whose properties + * will be modified according to the underlying Action + * object. As ActionButton inherits from Action, you can + * define your button's behavior right through this wrapper. + * + * \see Action + * + * \param button the QAbstractButton to associate to this ActionButton + * \param actionId the action Id to create the underlying Action + * \param parent the parent object + */ + explicit ActionButton(QAbstractButton *button, const QString &actionId = QString(), QObject *parent = 0); + virtual ~ActionButton(); + + /** + * Sets the button associated to the underlying action. + * + * \note If you are calling this function, you're probably + * changing the button the action is referring to. If this + * is the case, please note that Polkit-Qt does not handle + * the previous button's memory, so you should take care of + * deleting it yourself (if needed). You can retrieve it by + * using button() + * + * \see button + * + * \param button the new button associated with the underlying action + */ + void setButton(QAbstractButton *button); + + /** + * Returns the current button + * + * \return the button currently associated with the underlying action + */ + QAbstractButton *button() const; + +public Q_SLOTS: + /** + * Connect clicked() signals to this slot. This should be + * manually done, as in some cases we might want + * to manually call this. Calling this will emit authorized(). + * + * \note This slot is reentrant which is likely to only be a problem + * if you are creating an interface to setup PolicyKit policies. + * \note If you have a checkbox, connect to its' clicked() signal + * to avoid an infinite loop as this function internally calls setChecked(). + * You can always use the clicked(bool) signal in this class to + * connect to here. + * \warning if you use this class take care to not call Action::activate + * otherwise your checkable buttons won't be properly updated. + */ + bool activate(); + +Q_SIGNALS: + /** + * Emitted when the abstract button clicked(bool) signal + * is emitted. This allows you to use qobject_cast<ActionButton *>(sender()) + * in a slot connected to this signal and call activate() on it. + * + * \note you will normally want to connect this signal + * to the activate slot. + * + * \param button the button that has been clicked + * \param checked the checked state, if applicable. Otherwise \c false + * + */ + void clicked(QAbstractButton *button, bool checked = false); + +protected: + ActionButton(ActionButtonPrivate &dd, const QString &actionId, QObject *parent = 0); + + ActionButtonPrivate * const d_ptr; + +private: + Q_PRIVATE_SLOT(d_func(), void updateButton()) + Q_PRIVATE_SLOT(d_func(), void streamClicked(bool)) +}; + +} + +} + +#endif diff --git a/gui/polkitqt1-gui-actionbutton_p.h b/gui/polkitqt1-gui-actionbutton_p.h new file mode 100644 index 000000000..1f072b1e7 --- /dev/null +++ b/gui/polkitqt1-gui-actionbutton_p.h @@ -0,0 +1,50 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Dario Freddi <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef POLKITQT1_GUI_ACTIONBUTTON_P_H +#define POLKITQT1_GUI_ACTIONBUTTON_P_H + +#include <polkitqt1-gui-actionbutton.h> + +#include <QtCore/QList> +#include <QtGui/QAbstractButton> + +/** + * \internal + */ +class PolkitQt1::Gui::ActionButtonPrivate +{ +public: + ActionButtonPrivate(const QList<QAbstractButton *> &b) + : buttons(b) {} + virtual ~ActionButtonPrivate() {} + + void addButton(QAbstractButton *button); + void removeButton(QAbstractButton *button); + void updateButton(); + void streamClicked(bool); + + Q_DECLARE_PUBLIC(ActionButton) + ActionButton *q_ptr; + + QList<QAbstractButton *> buttons; +}; + +#endif /* ACTIONBUTTON_P_H */ diff --git a/gui/polkitqt1-gui-actionbuttons.cpp b/gui/polkitqt1-gui-actionbuttons.cpp new file mode 100644 index 000000000..242d41f71 --- /dev/null +++ b/gui/polkitqt1-gui-actionbuttons.cpp @@ -0,0 +1,73 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Dario Freddi <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "polkitqt1-gui-actionbuttons.h" + +#include "polkitqt1-gui-actionbuttons_p.h" + +namespace PolkitQt1 +{ + +namespace Gui +{ + +ActionButtons::ActionButtons(const QList<QAbstractButton *> &buttons, const QString &actionId, QObject *parent) + : ActionButton(*new ActionButtonsPrivate(buttons), actionId, parent) +{ + setButtons(buttons); +} + +ActionButtons::~ActionButtons() +{ +} + +void ActionButtons::setButtons(const QList<QAbstractButton *> &buttons) +{ + Q_FOREACH(QAbstractButton *ent, buttons) { + addButton(ent); + } +} + +QList<QAbstractButton *> ActionButtons::buttons() const +{ + Q_D(const ActionButtons); + + return d->buttons; +} + +void ActionButtons::addButton(QAbstractButton *button) +{ + Q_D(ActionButtons); + + d->addButton(button); +} + +void ActionButtons::removeButton(QAbstractButton *button) +{ + Q_D(ActionButtons); + + d->removeButton(button); +} + +} + +} + +#include "polkitqt1-gui-actionbuttons.moc" diff --git a/gui/polkitqt1-gui-actionbuttons.h b/gui/polkitqt1-gui-actionbuttons.h new file mode 100644 index 000000000..b02ddb902 --- /dev/null +++ b/gui/polkitqt1-gui-actionbuttons.h @@ -0,0 +1,114 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Dario Freddi <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef POLKITQT1_GUI_ACTIONBUTTONS_H +#define POLKITQT1_GUI_ACTIONBUTTONS_H + +#include "polkitqt1-gui-actionbutton.h" + +namespace PolkitQt1 +{ + +namespace Gui +{ + +class ActionButtonsPrivate; +/** + * \class ActionButtons polkitqt1-gui-actionbuttons.h ActionButtons + * \author Dario Freddi <[email protected]> + * + * \brief Class used to hold and update a list of QAbstractButtons + * + * This class is a convenience wrapper around ActionButton that lets + * you associate an undefined number of QAbstractButtons with a single + * action. Every button will be updated accordingly upon action's properties + * changes. + * + * \see ActionButton + */ +class ActionButtons : public ActionButton +{ + Q_OBJECT + Q_DECLARE_PRIVATE(ActionButtons) + Q_DISABLE_COPY(ActionButtons) + +public: + /** + * Constructs a new ActionButton. You need to pass this + * constructor an existing list of QAbstractButtons, whose properties + * will be modified according to the underlying Action + * object. As ActionButtons inherits from Action, you can + * define your buttons' behavior right through this wrapper. + * + * \see Action + * + * \param buttons the QAbstractButton to associate to this ActionButton + * \param actionId the action Id to create the underlying Action + * \param parent the parent object + */ + explicit ActionButtons(const QList<QAbstractButton *> &buttons, const QString &actionId = QString(), QObject *parent = 0); + virtual ~ActionButtons(); + + /** + * Sets a list of buttons associated to the underlying action. + * + * \note If you are calling this function, you're probably + * changing the buttons list the action is referring to. If this + * is the case, please note that Polkit-Qt does not handle + * the previous buttons' memory, so you should take care of + * deleting them yourself (if needed). You can retrieve it by + * using buttons() + * + * \see buttons + * + * \param buttons the new buttons associated with the underlying action + */ + void setButtons(const QList<QAbstractButton *> &buttons); + + /** + * Returns the current buttons list + * + * \return the buttons currently associated with the underlying action + */ + QList<QAbstractButton *> buttons() const; + + /** + * Adds a button to the current button list. The button's properties + * will be updated according to the action upon adding. + * + * \param button the button to add + */ + void addButton(QAbstractButton *button); + + /** + * Removes a button from the current list. Please note that Polkit-Qt + * does not handle the removed button's memory, so you should take care of + * deleting it yourself (if needed). + * + * \param button the button to remove + */ + void removeButton(QAbstractButton *button); +}; + +} + +} + +#endif diff --git a/gui/polkitqt1-gui-actionbuttons_p.h b/gui/polkitqt1-gui-actionbuttons_p.h new file mode 100644 index 000000000..c334d301c --- /dev/null +++ b/gui/polkitqt1-gui-actionbuttons_p.h @@ -0,0 +1,36 @@ +/* + * This file is part of the Polkit-qt project + * Copyright (C) 2009 Dario Freddi <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef POLKITQT1_GUI_ACTIONBUTTONS_P_H +#define POLKITQT1_GUI_ACTIONBUTTONS_P_H + +#include "polkitqt1-gui-actionbutton_p.h" + +/** + * \internal + */ +class PolkitQt1::Gui::ActionButtonsPrivate : public ActionButtonPrivate +{ +public: + ActionButtonsPrivate(const QList<QAbstractButton *> &b) + : ActionButtonPrivate(b) {} +}; + +#endif /* ACTIONBUTTONS_P_H */ |