convert the toolbox to use qactions. this makes the toolbox act a bit more reliably, makes some other bugs more annoying, and makes it easier to fix them.

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=811914
This commit is contained in:
Chani Armitage 2008-05-24 01:48:36 +00:00
parent ec0c7486b7
commit 3dcf445db4
7 changed files with 157 additions and 132 deletions

View File

@ -168,6 +168,13 @@ void Containment::init()
zoomAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); zoomAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
zoomAction->setShortcut(QKeySequence("ctrl+-")); zoomAction->setShortcut(QKeySequence("ctrl+-"));
d->actions().addAction("zoom out", zoomAction); d->actions().addAction("zoom out", zoomAction);
d->toolBox->addTool(this->action("add widgets"));
d->toolBox->addTool(this->action("zoom in"));
d->toolBox->addTool(this->action("zoom out"));
if (immutability() != SystemImmutable) {
d->toolBox->addTool(this->action("lock widgets"));
}
} }
Applet::init(); Applet::init();
@ -276,24 +283,12 @@ void Containment::setContainmentType(Containment::Type type)
if (isContainment() && type == DesktopContainment) { if (isContainment() && type == DesktopContainment) {
if (!d->toolBox) { if (!d->toolBox) {
QGraphicsWidget *addWidgetTool = addToolBoxTool("addwidgets", "list-add", i18n("Add Widgets")); d->createToolBox();
connect(addWidgetTool, SIGNAL(clicked()), this, SLOT(triggerShowAddWidgets()));
QGraphicsWidget *zoomInTool = addToolBoxTool("zoomIn", "zoom-in", i18n("Zoom In"));
connect(zoomInTool, SIGNAL(clicked()), this, SLOT(zoomIn()));
QGraphicsWidget *zoomOutTool = addToolBoxTool("zoomOut", "zoom-out", i18n("Zoom Out"));
connect(zoomOutTool, SIGNAL(clicked()), this, SLOT(zoomOut()));
if (immutability() != SystemImmutable) {
QGraphicsWidget *lockTool = addToolBoxTool("lockWidgets", "object-locked",
immutability() == UserImmutable ? i18n("Unlock Widgets") :
i18n("Lock Widgets"));
connect(lockTool, SIGNAL(clicked()), this, SLOT(toggleDesktopImmutability()));
}
/* FIXME activity action
QGraphicsWidget *activityTool = addToolBoxTool("addSiblingContainment", "list-add", i18n("Add Activity")); QGraphicsWidget *activityTool = addToolBoxTool("addSiblingContainment", "list-add", i18n("Add Activity"));
connect(activityTool, SIGNAL(clicked()), this, SLOT(addSiblingContainment())); connect(activityTool, SIGNAL(clicked()), this, SLOT(addSiblingContainment()));
*/
} }
} else if (isContainment() && type == PanelContainment) { } else if (isContainment() && type == PanelContainment) {
if (!d->toolBox) { if (!d->toolBox) {
@ -817,37 +812,27 @@ QVariant Containment::itemChange(GraphicsItemChange change, const QVariant &valu
return Applet::itemChange(change, value); return Applet::itemChange(change, value);
} }
QGraphicsWidget * Containment::addToolBoxTool(const QString& toolName, const QString& iconName, const QString& iconText) void Containment::enableAction(const QString &name, bool enable)
{ {
Plasma::Icon *tool = new Plasma::Icon(this); QAction *action = this->action(name);
if (action) {
tool->setDrawBackground(true); action->setEnabled(enable);
tool->setIcon(KIcon(iconName)); action->setVisible(enable);
tool->setText(iconText); }
tool->setOrientation(Qt::Horizontal);
QSizeF iconSize = tool->sizeFromIconSize(22);
tool->setMinimumSize(iconSize);
tool->setMaximumSize(iconSize);
tool->resize(tool->size());
d->createToolBox()->addTool(tool, toolName);
return tool;
} }
void Containment::enableToolBoxTool(const QString &toolname, bool enable) void Containment::addToolboxTool(QAction *action)
{ {
if (d->toolBox) { if (d->toolBox) {
d->toolBox->enableTool(toolname, enable); d->toolBox->addTool(action);
} }
} }
bool Containment::isToolBoxToolEnabled(const QString &toolname) const void Containment::removeToolboxTool(QAction *action)
{ {
if (d->toolBox) { if (d->toolBox) {
return d->toolBox->isToolEnabled(toolname); d->toolBox->removeTool(action);
} }
return false;
} }
void Containment::setToolBoxOpen(bool open) void Containment::setToolBoxOpen(bool open)
@ -1070,24 +1055,6 @@ void Containment::Private::handleDisappeared(AppletHandle *handle)
handle->deleteLater(); handle->deleteLater();
} }
void Containment::Private::setLockToolText()
{
if (!toolBox) {
return;
}
Icon *icon = dynamic_cast<Plasma::Icon*>(toolBox->tool("lockWidgets"));
if (icon) {
// we know it's an icon becase we made it
icon->setText(q->immutability() != Mutable ? i18n("Unlock Widgets") :
i18n("Lock Widgets"));
QSizeF iconSize = icon->sizeFromIconSize(22);
icon->setMinimumSize(iconSize);
icon->setMaximumSize(iconSize);
icon->resize(icon->size());
}
}
void Containment::Private::containmentConstraintsEvent(Plasma::Constraints constraints) void Containment::Private::containmentConstraintsEvent(Plasma::Constraints constraints)
{ {
if (!q->isContainment()) { if (!q->isContainment()) {
@ -1096,7 +1063,6 @@ void Containment::Private::containmentConstraintsEvent(Plasma::Constraints const
//kDebug() << "got containmentConstraintsEvent" << constraints << (QObject*)toolBox; //kDebug() << "got containmentConstraintsEvent" << constraints << (QObject*)toolBox;
if (constraints & Plasma::ImmutableConstraint) { if (constraints & Plasma::ImmutableConstraint) {
setLockToolText();
//update actions //update actions
bool unlocked = q->immutability() == Mutable; bool unlocked = q->immutability() == Mutable;
QAction *action = actions().action("add widgets"); QAction *action = actions().action("add widgets");
@ -1127,7 +1093,7 @@ void Containment::Private::containmentConstraintsEvent(Plasma::Constraints const
if ((constraints & Plasma::SizeConstraint || constraints & Plasma::ScreenConstraint) && if ((constraints & Plasma::SizeConstraint || constraints & Plasma::ScreenConstraint) &&
toolBox) { toolBox) {
positionToolBox(); positionToolBox();
toolBox->enableTool("addwidgets", q->immutability() == Mutable); //toolBox->enableTool("addwidgets", q->immutability() == Mutable);
} }
if (constraints & Plasma::FormFactorConstraint) { if (constraints & Plasma::FormFactorConstraint) {

View File

@ -220,28 +220,22 @@ class PLASMA_EXPORT Containment : public Applet
void restore(KConfigGroup &group); void restore(KConfigGroup &group);
/** /**
* Constructs a ToolBox item and adds it to the toolbox. The toolbox takes over ownership of the item. Returns the constructed tool. * convenience function - enables or disables an action by name
* *
* @param toolName the name of the tool * @param name the name of the action in our collection
* @param iconName the name of the icon
* @param iconText the text to be displayed on the icon
*
* @return the constructed tool
*/
QGraphicsWidget* addToolBoxTool(const QString &toolName = QString(), const QString &iconName = QString(), const QString &iconText = QString());
/**
* Enables or disables a toolbox tool by name
*
* @param toolName the name of the tool
* @param enable true to enable, false to disable * @param enable true to enable, false to disable
*/ */
void enableToolBoxTool(const QString &toolName, bool enable); void enableAction(const QString &name, bool enable);
/** /**
* Returns whether or not a given toolbox tool is enabled * Add an action to the toolbox
*/ */
bool isToolBoxToolEnabled(const QString &toolName) const; void addToolboxTool(QAction *action);
/**
* Remove an action from the toolbox
*/
void removeToolboxTool(QAction *action);
/** /**
* Sets the open or closed state of the Containment's toolbox * Sets the open or closed state of the Containment's toolbox

View File

@ -21,21 +21,20 @@
#include "toolbox_p.h" #include "toolbox_p.h"
#include <QAction>
#include <QGraphicsSceneHoverEvent> #include <QGraphicsSceneHoverEvent>
#include <QPainter> #include <QPainter>
#include <QRadialGradient> #include <QRadialGradient>
#include <plasma/theme.h>
#include <KColorScheme> #include <KColorScheme>
#include <KDebug> #include <KDebug>
#include <plasma/theme.h>
#include "widgets/icon.h"
namespace Plasma namespace Plasma
{ {
// used with QGrahphicsItem::setData
static const int ToolName = 7001;
class Toolbox::Private class Toolbox::Private
{ {
public: public:
@ -66,57 +65,50 @@ Toolbox::~Toolbox()
delete d; delete d;
} }
void Toolbox::addTool(QGraphicsItem *tool, const QString &name) void Toolbox::addTool(QAction *action)
{ {
if (!tool) { if (!action) {
return; return;
} }
Plasma::Icon *tool = new Plasma::Icon(this);
tool->setAction(action);
tool->setDrawBackground(true);
tool->setOrientation(Qt::Horizontal);
QSizeF iconSize = tool->sizeFromIconSize(22);
tool->setMinimumSize(iconSize);
tool->setMaximumSize(iconSize);
tool->resize(tool->size());
tool->hide(); tool->hide();
const int height = static_cast<int>(tool->boundingRect().height()); const int height = static_cast<int>(tool->boundingRect().height());
tool->setPos(QPoint( d->size*2,-height)); tool->setPos(QPoint( d->size*2,-height));
tool->setZValue(zValue() + 1); tool->setZValue(zValue() + 1);
tool->setParentItem(this);
tool->setData(ToolName, name); //make enabled/disabled tools appear/disappear instantly
connect(tool, SIGNAL(changed()), this, SLOT(updateToolbox()));
} }
void Toolbox::enableTool(const QString &toolName, bool visible) void Toolbox::updateToolbox()
{ {
//kDebug() << (visible? "enabling" : "disabling") << "tool" << toolName;
QGraphicsItem *t = tool(toolName);
if (t && t->isEnabled() != visible) {
t->setEnabled(visible);
// adjust the visible items
if ( d->showing) { if ( d->showing) {
d->showing = false; d->showing = false;
showToolbox(); showToolbox();
} }
} }
}
bool Toolbox::isToolEnabled(const QString &toolName) const void Toolbox::removeTool(QAction *action)
{
QGraphicsItem *t = tool(toolName);
if (t) {
return t->isEnabled();
}
return false;
}
QGraphicsItem* Toolbox::tool(const QString &toolName) const
{ {
foreach (QGraphicsItem *child, QGraphicsItem::children()) { foreach (QGraphicsItem *child, QGraphicsItem::children()) {
//kDebug() << "checking tool" << child << child->data(ToolName); //kDebug() << "checking tool" << child << child->data(ToolName);
if (child->data(ToolName).toString() == toolName) { Plasma::Icon *tool = dynamic_cast<Plasma::Icon*>(child);
if (tool && tool->action() == action) {
//kDebug() << "tool found!"; //kDebug() << "tool found!";
return child; tool->deleteLater();
break;
} }
} }
return 0;
} }
int Toolbox::size() const int Toolbox::size() const

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU Library General Public License as * it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or * published by the Free Software Foundation; either version 2, or
* (at your option) any later version. * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -26,11 +26,13 @@
#include "animator.h" #include "animator.h"
class QAction;
namespace Plasma namespace Plasma
{ {
class Widget; //class Widget;
class EmptyGraphicsItem; //class EmptyGraphicsItem;
class Toolbox : public QObject, public QGraphicsItem class Toolbox : public QObject, public QGraphicsItem
{ {
@ -40,10 +42,15 @@ public:
explicit Toolbox(QGraphicsItem *parent = 0); explicit Toolbox(QGraphicsItem *parent = 0);
~Toolbox(); ~Toolbox();
void addTool(QGraphicsItem *tool, const QString &name); /**
void enableTool(const QString &tool, bool enabled); * create a toolbox tool from the given action
bool isToolEnabled(const QString &tool) const; * @p action the action to associate hte tool with
QGraphicsItem* tool(const QString &tool) const; */
void addTool(QAction *action);
/**
* remove the tool associated with this action
*/
void removeTool(QAction *action);
int size() const; int size() const;
void setSize(const int newSize); void setSize(const int newSize);
QSize iconSize() const; QSize iconSize() const;
@ -55,7 +62,11 @@ public:
virtual void showToolbox() = 0; virtual void showToolbox() = 0;
virtual void hideToolbox() = 0; virtual void hideToolbox() = 0;
public Q_SLOTS:
/**
* re-show the toolbox, in case any tools have changed
*/
void updateToolbox();
Q_SIGNALS: Q_SIGNALS:
void toggled(); void toggled();

View File

@ -58,14 +58,16 @@
namespace Plasma namespace Plasma
{ {
Icon::Private::Private() Icon::Private::Private(Icon *i)
: iconSvg(0), : q(i),
iconSvg(0),
iconSize(48, 48), iconSize(48, 48),
states(Private::NoState), states(Private::NoState),
orientation(Qt::Vertical), orientation(Qt::Vertical),
numDisplayLines(2), numDisplayLines(2),
invertLayout(false), invertLayout(false),
drawBg(false) drawBg(false),
action(0)
{ {
m_hoverAnimId = -1; m_hoverAnimId = -1;
m_hoverAlpha = 20/255; m_hoverAlpha = 20/255;
@ -258,14 +260,14 @@ void IconAction::paint(QPainter *painter) const
Icon::Icon(QGraphicsItem *parent) Icon::Icon(QGraphicsItem *parent)
: QGraphicsWidget(parent), : QGraphicsWidget(parent),
d(new Private) d(new Private(this))
{ {
init(); init();
} }
Icon::Icon(const QString &text, QGraphicsItem *parent) Icon::Icon(const QString &text, QGraphicsItem *parent)
: QGraphicsWidget(parent), : QGraphicsWidget(parent),
d(new Private) d(new Private(this))
{ {
setText(text); setText(text);
init(); init();
@ -273,7 +275,7 @@ Icon::Icon(const QString &text, QGraphicsItem *parent)
Icon::Icon(const QIcon &icon, const QString &text, QGraphicsItem *parent) Icon::Icon(const QIcon &icon, const QString &text, QGraphicsItem *parent)
: QGraphicsWidget(parent), : QGraphicsWidget(parent),
d(new Private) d(new Private(this))
{ {
setText(text); setText(text);
setIcon(icon); setIcon(icon);
@ -311,11 +313,11 @@ void Icon::init()
//setDrawStandardBackground(false); //setDrawStandardBackground(false);
} }
void Icon::addAction(QAction *action) void Icon::addIconAction(QAction *action)
{ {
int count = d->cornerActions.count(); int count = d->cornerActions.count();
if (count > 3) { if (count > 3) {
kDebug() << "Icon::addAction(QAction*) no more room for more actions!"; kDebug() << "no more room for more actions!";
} }
IconAction* iconAction = new IconAction(this, action); IconAction* iconAction = new IconAction(this, action);
@ -325,6 +327,25 @@ void Icon::addAction(QAction *action)
iconAction->setRect(d->actionRect((Private::ActionPosition)count)); iconAction->setRect(d->actionRect((Private::ActionPosition)count));
} }
void Icon::setAction(QAction *action)
{
if (d->action) {
disconnect(d->action, 0, this, 0);
disconnect(this, 0, d->action, 0);
}
d->action = action;
if (action) {
connect(action, SIGNAL(changed()), this, SLOT(syncToAction()));
connect(this, SIGNAL(clicked()), action, SLOT(trigger()));
d->syncToAction();
}
}
QAction* Icon::action() const
{
return d->action;
}
void Icon::actionDestroyed(QObject* action) void Icon::actionDestroyed(QObject* action)
{ {
QList<IconAction*>::iterator it = d->cornerActions.begin(); QList<IconAction*>::iterator it = d->cornerActions.begin();
@ -1103,6 +1124,21 @@ void Icon::setUnpressed()
setPressed(false); setPressed(false);
} }
void Icon::Private::syncToAction()
{
if (!action) {
return;
}
//we don't get told *what* changed, just that something changed
//so we update everything we care about
q->setIcon(action->icon());
q->setText(action->iconText());
q->setEnabled(action->isEnabled());
//TODO use action's tooltip too
emit q->changed();
}
void Icon::setOrientation(Qt::Orientation orientation) void Icon::setOrientation(Qt::Orientation orientation)
{ {
d->orientation = orientation; d->orientation = orientation;

View File

@ -54,6 +54,7 @@ class PLASMA_EXPORT Icon : public QGraphicsWidget
Q_PROPERTY( QIcon icon READ icon WRITE setIcon ) Q_PROPERTY( QIcon icon READ icon WRITE setIcon )
Q_PROPERTY( QSizeF iconSize READ iconSize ) Q_PROPERTY( QSizeF iconSize READ iconSize )
Q_PROPERTY( QString svg WRITE setSvg ) Q_PROPERTY( QString svg WRITE setSvg )
// Q_PROPERTY( QAction action READ action WRITE setAction )
public: public:
/** /**
* Creates a new Plasma::Icon. * Creates a new Plasma::Icon.
@ -136,12 +137,24 @@ public:
/** /**
* Plasma::Icon allows the user to specify a number of actions * Plasma::Icon allows the user to specify a number of actions
* (current four) to be displayed around the widget. This method * (currently four) to be displayed around the widget. This method
* allows for a created QAction (not a KAction!) to be added to * allows for a created QAction to be added to the Plasma::Icon.
* the Plasma::Icon.
* @param action the QAction to associate with this icon. * @param action the QAction to associate with this icon.
*/ */
void addAction(QAction* action); void addIconAction(QAction* action);
/**
* Associate an action with this Icon
* this makes the Icon follow the state of the action, using its icon, text, etc.
* when the Icon is clicked, it will also trigger the action.
* Unlike addIconAction, there can be only one associated action.
*/
void setAction(QAction *action);
/**
* @return the currently associated action, if any.
*/
QAction* action() const;
/** /**
* let set the orientation of the icon * let set the orientation of the icon
@ -235,6 +248,12 @@ Q_SIGNALS:
*/ */
void activated(); void activated();
/**
* Indicates that something about the icon may have changed (image, text, etc)
* only actually works for icons associated with an action
*/
void changed();
protected: protected:
bool isDown(); bool isDown();
void mousePressEvent(QGraphicsSceneMouseEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *event);
@ -254,6 +273,7 @@ public:
void drawActionButtonBase(QPainter* painter, const QSize &size, int element); void drawActionButtonBase(QPainter* painter, const QSize &size, int element);
private: private:
Q_PRIVATE_SLOT(d, void syncToAction())
void init(); void init();
void layoutIcons(const QStyleOptionGraphicsItem *option); void layoutIcons(const QStyleOptionGraphicsItem *option);
void hoverEffect(bool); void hoverEffect(bool);

View File

@ -103,7 +103,7 @@ public:
Q_DECLARE_FLAGS(IconStates, IconState) Q_DECLARE_FLAGS(IconStates, IconState)
public: public:
Private(); Private(Icon *i);
~Private(); ~Private();
void drawBackground(QPainter *painter, IconState state); void drawBackground(QPainter *painter, IconState state);
@ -162,7 +162,12 @@ public:
inline QSizeF subtractMargin(const QSizeF &size, MarginType type) const; inline QSizeF subtractMargin(const QSizeF &size, MarginType type) const;
inline QRectF actionRect(ActionPosition position) const; inline QRectF actionRect(ActionPosition position) const;
/**
* update the icon's text, icon, etc. to reflect the properties of its associated action.
*/
void syncToAction();
Icon *q;
QString text; QString text;
QString infoText; QString infoText;
Svg *iconSvg; Svg *iconSvg;
@ -184,6 +189,7 @@ public:
QPointF clickStartPos; QPointF clickStartPos;
QList<IconAction*> cornerActions; QList<IconAction*> cornerActions;
QAction *action;
Margin verticalMargin[NMargins]; Margin verticalMargin[NMargins];
Margin horizontalMargin[NMargins]; Margin horizontalMargin[NMargins];