Description
It's a subclass of QAction that takes a StringID to call a slot on its target. To use Cocoa terms, the StringID is the "selector" that the CmdAction will call on the target. The target just needs to implement Responder and write a slot that takes a single QVariant as its parameter. Since CmdAction has a "data" property (from QAction) it can send that to the target in the slot.
The way that you'd make a toolbar or menus is to make CmdActions and give them StringIDs (like "cut", "copy", or "openHelp"). Then, you can make your widgets inherit Responder and implement slots (like "cut(const QVariant &)". When that widget has focus, a method will be called on it "customizeAction()" and it can alter the CmdAction's state. This is very similar to menu and toolbar validation on the Mac.
http://developer.apple.com/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html
http://developer.apple.com/documentation/Cocoa/Conceptual/Toolbars/Tasks/ValidatingTBItems.html
If this were built into Qt, via QObject, our lives would be so much easier. There may be a way for me to implement this without having a Responder subclass.
CmdTargetDesc is just a way of specifying who the target of the CmdAction is. You can use it to say: "global focus widget" or "focus of this top-level widget" or "always this object".
class CmdAction : public QAction, public Targetable
{ Q_OBJECT Q_PROPERTY( StringID commandID READ commandID ) Q_PROPERTY( CmdTargetDesc targetDescription READ targetDescription WRITE setTargetDescription ) Q_PROPERTY( bool autoValidated READ isAutoValidated WRITE setAutoValidated ) Q_PROPERTY( QString defaultMenuText READ defaultMenuText WRITE setDefaultMenuText ) public: CmdAction( const StringID & commandID, QObject * parent ); CmdAction( const StringID & commandID, QObject * focusHolder, CmdTargetDesc::FocusType focusType, QObject * parent ); CmdAction( const StringID & commandID, const CmdTargetDesc & desc, QObject * parent ); CmdAction( const StringID & commandID, const CmdTargetDesc & desc, const QString & text, QObject * parent ); CmdAction( const StringID & commandID, const CmdTargetDesc & desc, const QIcon & icon, const QString & text, QObject * parent ); void setDefaultMenuText( const QString & text ); QString defaultMenuText() const; }; class Responder : public QObjectInheritance { public: Responder( QObject * ); virtual ~Responder(); virtual void customizeAction ( const StringID & cmd, QAction * a); };
... sample class ...
class TextEdit : public QTextEdit
{ Q_OBJECT public: TextEdit(QObject * parent = NULL); // These can all be called by CmdActions dynamically public slots: void cut (const QVariant & d = QVariant()); void copy (const QVariant & d = QVariant()); void paste(const QVariant & d = QVariant()); };