The future of KAction

Hamish Rodda rodda at kde.org
Tue Nov 15 13:52:17 GMT 2005


On Wednesday 16 November 2005 00:02, Simon Hausmann wrote:
> On Friday 11 November 2005 20:06, David Faure wrote:
> > On Friday 11 November 2005 07:38, Hamish Rodda wrote:
> > > The other big change that I can see is that the plugging and unplugging
> > > moves to be each widget's responsibility.
> >
> > That's the huge change, which I'm not too comfortable with.
> > If you want a special action in a toolbar, like say a
> > koffice-color-chooser toolbar button with popup, the solution was to
> > inherit from KAction and reimplement plug. But if now the responsibility
> > is in the widget, how do we do that? Subclassing QToolbar in an
> > application sounds like the really wrong way to attack the problem,
> > doesn't it?
> >
> > (Of course this example has other solutions, like a way to set a popup to
> > a standard toolbar button, but there are many other cases of custom
> > actions...)
>
> The reason why we have KWidgetAction is because of the way the toolbars are
> built, using xmlgui which only accepts xml and actions as input.
>
> So we have KAction used for two different things:
>
> 1) Centralizing properties for user actions
> 2) As a way to pass a widget to a toolbar because the API for populating
> doesn't permit specifying a widget directly anywhere.
>
> The latter is strange if you think about it, it's not using any of the
> properties of an action. You don't get an activated signal, it doesn't use
> the text(), icon() or toolTip() property. It's essentially not an action in
> the original sense of it.
>
> Now I agree that requiring subclassing of QToolBar is the wrong solution,
> especially given that QToolBar has a addWidget() method.
>
> A much better solution IMHO is to provide a better API for populating the
> menus and toolbars, an API that also allows specifying actions and widgets
> but still provides features like place holders which plugins can populate
> with their actions for example.
>
> Here's an example of a quite stateful API that I have in mind (with
> improvements thanks to a discussion with Benjamin):
>
> GuiEditor editor(this);
>
> editor.startMenuBar();
>
>   editor.startMenu("file", "&File");
>
>     editor.addAction(newDocumentAction);
>     editor.addAction(fileOpenAction);
>     editor.addSeparator();
>
>     editor.startMenu("printTo", "&Print To");
>       editor.addActions(KPrinter::printToActions());
>     editor.menuFinished();
>
>     editor.addSeparator();
>     editor.addAction(quitAction);
>
>   editor.menuFinished();
>
>    ...
>    editor.startMenu("settings", "&Settings");
>      ...
>      editor.addActionGroup("plugin settings");
>      ...
>    editor.menuFinished();
>    ...
>
> editor.menuFinished();
>
> editor.startToolBar();
>
>   editor.addAction(newDocumentAction);
>   editor.addSeparator();
>   editor.addWidget(searchComboBox);
>
> editor.show();
>
> For a plugin the concept of providing a actions and its desired locations
> in menus and toolbars is very similar to painting: Called on-demand it can
> be asked to describe what it would like. Hence the idea of plugins
> implementing a simple interface that consists of a method looking similar
> to a paintEvent:
>
> void Plugin::buildGui()
> {
>     GuiEditor editor(this);
>
>     editor.startMenuBar();
>     // .. in case the application doesn't want us to populate
>     // the settings menu or doesn't provide one in the first place
>     if (editor.tryToEditMenu("settings")) {
>         editor.addActionToGroup("plugin settings", mySettingsAction);
>     }
>     ....
>
>     editor.menuFinished();
>
>     editor.startToolBar("plugin toolbar");
>       editor.addAction(...);
>       editor.addWidget(...);
>     editor.toolBarFinished();
> }
>
> How does that look?

I like the proposed GUI building API, it seems cleaner and more 
self-documenting.  It would also allow us to remove the "const char* name" 
parameter from KAction's constructors, while still allowing for a non-verbose 
API.

However, are you saying that KAction should not provide custom widgets, and if 
they are needed that each application should code the custom widget?  
Although it is idealistically more pure, I would suggest that it does not 
promote code reuse as much as if KAction could provide the custom widget. Eg:

class KColorAction : public KAction
{
<blah>

	const QColor& currentColor() const;
	void setCurrentColor(const QColor& newColor);

protected:
	/// Overridden to provide the color selecting widget
	virtual QWidget* toolbarWidget();

public signals:
	void triggered(const QColor& newColor);
};

Even though the original signals (triggered(bool)) are less useful, they can 
provide their own signals which allows for encapsulation in a similar way to 
a regular action.

Cheers,
Hamish.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20051116/774ab592/attachment.sig>


More information about the kde-core-devel mailing list