File indexing completed on 2024-03-24 15:27:36
0001 /* This file is part of the KDE libraries 0002 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org> 0003 (C) 1999 Simon Hausmann <hausmann@kde.org> 0004 (C) 2000 Nicolas Hadacek <haadcek@kde.org> 0005 (C) 2000 Kurt Granroth <granroth@kde.org> 0006 (C) 2000 Michael Koch <koch@kde.org> 0007 (C) 2001 Holger Freyther <freyther@kde.org> 0008 (C) 2002 Ellis Whitehead <ellis@kde.org> 0009 (C) 2005-2006 Hamish Rodda <rodda@kde.org> 0010 0011 This library is free software; you can redistribute it and/or 0012 modify it under the terms of the GNU Library General Public 0013 License version 2 as published by the Free Software Foundation. 0014 0015 This library is distributed in the hope that it will be useful, 0016 but WITHOUT ANY WARRANTY; without even the implied warranty of 0017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0018 Library General Public License for more details. 0019 0020 You should have received a copy of the GNU Library General Public License 0021 along with this library; see the file COPYING.LIB. If not, write to 0022 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0023 Boston, MA 02110-1301, USA. 0024 */ 0025 0026 #ifndef KACTION_H 0027 #define KACTION_H 0028 0029 #include <kdelibs4support_export.h> 0030 #include <kauth/action.h> 0031 0032 #include <QWidgetAction> 0033 0034 class KShapeGesture; 0035 class KRockerGesture; 0036 class KShortcut; 0037 0038 //TODO Reduce the word count. This is not very focused and takes too long to read. 0039 //Keep in mind that QAction also has documentation that we don't need to repeat here. 0040 /** 0041 * @short Class to encapsulate user-driven action or event 0042 * @extends QAction 0043 * 0044 * The KAction class (and derived and super classes) extends QAction, 0045 * which provides a way to easily encapsulate a "real" user-selected 0046 * action or event in your program. 0047 * 0048 * For instance, a user may want to @p paste the contents of 0049 * the clipboard, @p scroll @p down a document, or @p quit the 0050 * application. These are all \b actions -- events that the 0051 * user causes to happen. The KAction class allows the developer to 0052 * deal with these actions in an easy and intuitive manner, and conforms 0053 * to KDE's extended functionality requirements - including supporting 0054 * multiple user-configurable shortcuts, and KDE named icons. Actions 0055 * also improve accessibility. 0056 * 0057 * Specifically, QAction (and thus KAction) encapsulates the various attributes 0058 * of an event/action. For instance, an action might have an icon() 0059 * that provides a visual representation (a clipboard for a "paste" action or 0060 * scissors for a "cut" action). The action should also be described by some text(). 0061 * It will certainly be connected to a method that actually @p executes the action! 0062 * All these attributes are contained within the action object. 0063 * 0064 * The advantage of dealing with actions is that you can manipulate 0065 * the Action without regard to the GUI representation of it. For 0066 * instance, in the "normal" way of dealing with actions like "cut", 0067 * you would manually insert a item for Cut into a menu and a button 0068 * into a toolbar. If you want to disable the cut action for a moment 0069 * (maybe nothing is selected), you would have to hunt down the pointer 0070 * to the menu item and the toolbar button and disable both 0071 * individually. Setting the menu item and toolbar item up uses very 0072 * similar code - but has to be done twice! 0073 * 0074 * With the action concept, you simply add the action to whatever 0075 * GUI element you want. The KAction class will then take care of 0076 * correctly defining the menu item (with icons, accelerators, text, 0077 * etc), toolbar button, or other. From then on, if you 0078 * manipulate the action at all, the effect will propagate through all 0079 * GUI representations of it. Back to the "cut" example: if you want 0080 * to disable the Cut Action, you would simply call 0081 * 'cutAction->setEnabled(false)' and both the menuitem and button would 0082 * instantly be disabled! 0083 * 0084 * This is the biggest advantage to the action concept -- there is a 0085 * one-to-one relationship between the "real" action and @p all 0086 * GUI representations of it. 0087 * 0088 * KAction emits the hovered() signal on mouseover, and the triggered(bool checked) 0089 * signal on activation of a corresponding GUI element ( menu item, toolbar button, etc. ) 0090 * 0091 * If you are in the situation of wanting to map the triggered() 0092 * signal of multiple action objects to one slot, with a special 0093 * argument bound to each action, you have several options: 0094 * 0095 * Using QActionGroup: 0096 * \li Create a QActionGroup and assign it to each of the actions with setActionGroup(), then 0097 * \li Connect the QActionGroup::triggered(QAction*) signal to your slot. 0098 * 0099 * Using QSignalMapper: 0100 * \code 0101 * QSignalMapper *desktopNumberMapper = new QSignalMapper( this ); 0102 * connect( desktopNumberMapper, SIGNAL( mapped( int ) ), 0103 * this, SLOT( moveWindowToDesktop( int ) ) ); 0104 * 0105 * for ( uint i = 0; i < numberOfDesktops; ++i ) { 0106 * KAction *desktopAction = new KAction( i18n( "Move Window to Desktop %i" ).arg( i ), ... ); 0107 * connect( desktopAction, SIGNAL( triggered(bool) ), desktopNumberMapper, SLOT( map() ) ); 0108 * desktopNumberMapper->setMapping( desktopAction, i ); 0109 * } 0110 * \endcode 0111 * 0112 * \section kaction_general General Usage 0113 * 0114 * The steps to using actions are roughly as follows: 0115 * 0116 * @li Decide which attributes you want to associate with a given 0117 * action (icons, text, keyboard shortcut, etc) 0118 * @li Create the action using KAction (or derived or super class). 0119 * @li Add the action into whatever GUI element you want. Typically, 0120 * this will be a menu or toolbar. 0121 * 0122 * \section kaction_general The kinds of shortcuts 0123 * 0124 * Local shortcuts are active if their context has the focus, global shortcus 0125 * are active even if the program does not have the focus. If a global 0126 * shortcut and a local shortcut are ambiguous the global shortcut wins. 0127 * 0128 * @li Active shortcuts trigger a KAction if activated. 0129 * @li Default shortcuts are what the active shortcuts revert to if the user chooses 0130 * to reset shortcuts to default. 0131 * 0132 * \section kaction_example Detailed Example 0133 * 0134 * Here is an example of enabling a "New [document]" action 0135 * \code 0136 * KAction *newAct = actionCollection()->addAction( 0137 * KStandardAction::New, //< see KStandardAction 0138 * this, //< Receiver 0139 * SLOT(fileNew()) ); //< SLOT 0140 * \endcode 0141 * 0142 * This section creates our action. Text, Icon and Shortcut will be set from 0143 * KStandardAction. KStandardAction ensures your application complies to the 0144 * platform standards. When triggered the \c fileNew() slot will be called. 0145 * 0146 * @see KStandardAction for more information. 0147 * 0148 * If you want to create your own actions use 0149 * \code 0150 * KAction *newAct = actionCollection()->addAction("quick-connect"); 0151 * newAct->setText(i18n("Quick Connect")) 0152 * newAct->setIcon(QIcon::fromTheme("quick-connect")); 0153 * newAct->setShortcut(Qt::Key_F6); 0154 * connect(newAct, SIGNAL(triggered()), this, SLOT(quickConnect())); 0155 * \endcode 0156 * 0157 * This section creates our action. It displays the text "Quick Connect", 0158 * uses the Icon "quick-connect" and pressing \c F6 will trigger it. When 0159 * invoked, the slot quickConnect() is called. 0160 * 0161 * \code 0162 * QMenu *file = new QMenu; 0163 * file->addAction(newAct); 0164 * \endcode 0165 * That just inserted the action into the File menu. The point is, it's not 0166 * important in which menu it is: all manipulation of the item is 0167 * done through the newAct object. 0168 * 0169 * \code 0170 * toolBar()->addAction(newAct); 0171 * \endcode 0172 * And this added the action into the main toolbar as a button. 0173 * 0174 * That's it! 0175 * 0176 * If you want to disable that action sometime later, you can do so 0177 * with 0178 * \code 0179 * newAct->setEnabled(false) 0180 * \endcode 0181 * and both the menuitem in File and the toolbar button will instantly 0182 * be disabled. 0183 * 0184 * Unlike with previous versions of KDE, the action can simply be deleted 0185 * when you have finished with it - the destructor takes care of all 0186 * of the cleanup. 0187 * 0188 * \warning calling QAction::setShortcut() on a KAction may lead to unexpected 0189 * behavior. There is nothing we can do about it because QAction::setShortcut() 0190 * is not virtual. 0191 * 0192 * \note if you are using a "standard" action like "new", "paste", 0193 * "quit", or any other action described in the KDE UI Standards, 0194 * please use the methods in the KStandardAction class rather than 0195 * defining your own. 0196 * 0197 * \section Using QActions 0198 * 0199 * Mixing QActions and KActions in an application is not a 0200 * good idea. KShortcutsEditor doesn't handle QActions at all. 0201 * 0202 * \section kaction_xmlgui Usage Within the XML Framework 0203 * 0204 * If you are using KAction within the context of the XML menu and 0205 * toolbar building framework, you do not ever 0206 * have to add your actions to containers manually. The framework 0207 * does that for you. 0208 * 0209 * @see KStandardAction 0210 */ 0211 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KAction : public QWidgetAction 0212 { 0213 Q_OBJECT 0214 0215 Q_PROPERTY(KShortcut shortcut READ shortcut WRITE setShortcut) 0216 Q_PROPERTY(bool shortcutConfigurable READ isShortcutConfigurable WRITE setShortcutConfigurable) 0217 Q_PROPERTY(KShortcut globalShortcut READ globalShortcut WRITE setGlobalShortcut) 0218 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED 0219 Q_PROPERTY(bool globalShortcutAllowed READ globalShortcutAllowed WRITE setGlobalShortcutAllowed) 0220 #endif 0221 Q_PROPERTY(bool globalShortcutEnabled READ isGlobalShortcutEnabled) 0222 Q_FLAGS(ShortcutType) 0223 0224 public: 0225 /** 0226 * An enumeration about the two types of shortcuts in a KAction 0227 */ 0228 enum ShortcutType { 0229 /// The shortcut will immediately become active but may be reset to "default". 0230 ActiveShortcut = 0x1, 0231 /// The shortcut is a default shortcut - it becomes active when somebody decides to 0232 /// reset shortcuts to default. 0233 DefaultShortcut = 0x2 0234 }; 0235 Q_DECLARE_FLAGS(ShortcutTypes, ShortcutType) 0236 0237 /** 0238 * An enum about global shortcut setter semantics 0239 */ 0240 //This enum will be ORed with ShortcutType in calls to KGlobalAccel, so it must not contain 0241 //any value equal to a value in ShortcutType. 0242 enum GlobalShortcutLoading { 0243 /// Look up the action in global settings (using its main component's name and text()) 0244 /// and set the shortcut as saved there. 0245 /// @see setGlobalShortcut() 0246 Autoloading = 0x0, 0247 /// Prevent autoloading of saved global shortcut for action 0248 NoAutoloading = 0x4 0249 }; 0250 /** 0251 * Constructs an action. 0252 */ 0253 KDELIBS4SUPPORT_DEPRECATED explicit KAction(QObject *parent); 0254 0255 /** 0256 * Constructs an action with the specified parent and visible text. 0257 * 0258 * @param text The visible text for this action. 0259 * @param parent The parent for this action. 0260 */ 0261 KAction(const QString &text, QObject *parent); 0262 0263 /** 0264 * Constructs an action with text and icon; a shortcut may be specified by 0265 * the ampersand character (e.g. \"&Option\" creates a shortcut with key \e O ) 0266 * 0267 * This is the other common KAction constructor used. Use it when you 0268 * \e do have a corresponding icon. 0269 * 0270 * @param icon The icon to display. 0271 * @param text The text that will be displayed. 0272 * @param parent The parent for this action. 0273 */ 0274 KAction(const QIcon &icon, const QString &text, QObject *parent); 0275 0276 /** 0277 * Standard destructor 0278 */ 0279 ~KAction() override; 0280 0281 /** 0282 * Sets the help text for the action. 0283 * This help text will be set for all help mechanisms: 0284 * - the status-bar help text 0285 * - the tooltip (for toolbar buttons) 0286 * - the "WhatsThis" help text (unless one was already set) 0287 * 0288 * This is more convenient than calling all three methods with the 0289 * same text, and this level of abstraction can allow to change 0290 * the default implementation of help one day more easily. 0291 * Of course you can also call setStatusTip, setToolTip and setWhatsThis 0292 * separately for more flexibility. 0293 * 0294 * This method is also the easiest way to port from KDE3's KAction::setToolTip. 0295 * 0296 * @since 4.3 0297 */ 0298 void setHelpText(const QString &text); 0299 0300 /** 0301 * Get the shortcut for this action. 0302 * 0303 * This is preferred over QAction::shortcut(), as it allows for multiple shortcuts 0304 * per action. The first and second shortcut as reported by shortcuts() will be the 0305 * primary and alternate shortcut of the shortcut returned. 0306 * 0307 * \param types the type of shortcut to return. Should both be specified, only the 0308 * active shortcut will be returned. Defaults to the active shortcut, if one exists. 0309 * \sa shortcuts() 0310 */ 0311 KShortcut shortcut(ShortcutTypes types = ActiveShortcut) const; 0312 0313 /** 0314 * Set the shortcut for this action. 0315 * 0316 * This is preferred over QAction::setShortcut(), as it allows for multiple shortcuts 0317 * per action. 0318 * 0319 * \param shortcut shortcut(s) to use for this action in its specified shortcutContext() 0320 * \param type type of shortcut to be set: active shortcut, 0321 * default shortcut, or both (the default). 0322 */ 0323 void setShortcut(const KShortcut &shortcut, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut)); 0324 0325 /** 0326 * \overload void setShortcut(const KShortcut& shortcut) 0327 * 0328 * Set the primary shortcut only for this action. 0329 * 0330 * This function is there to explicitly override QAction::setShortcut(const QKeySequence&). 0331 * QAction::setShortcut() will bypass everything in KAction and may lead to unexpected behavior. 0332 * 0333 * \param shortcut shortcut(s) to use for this action in its specified shortcutContext() 0334 * \param type type of shortcut to be set: active shortcut, 0335 * default shortcut, or both (default argument value). 0336 */ 0337 void setShortcut(const QKeySequence &shortcut, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut)); 0338 0339 /** 0340 * \overload void setShortcuts(const QList\<QKeySequence\>& shortcuts). 0341 * 0342 * Set the shortcuts for this action. 0343 * 0344 * This function is there to explicitly override QAction::setShortcut(const QList\<QKeySequence\>&). 0345 * QAction::setShortcuts() will bypass everything in KAction and may lead to unexpected behavior. 0346 * 0347 * \param shortcut shortcut(s) to use for this action in its specified shortcutContext() 0348 * \param type type of shortcut to be set: active shortcut, 0349 * default shortcut, or both (default argument value). 0350 */ 0351 void setShortcuts(const QList<QKeySequence> &shortcuts, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut)); 0352 0353 /** 0354 * Returns true if this action's shortcut is configurable. 0355 */ 0356 bool isShortcutConfigurable() const; 0357 0358 /** 0359 * Indicate whether the user may configure the action's shortcut. 0360 * 0361 * \param configurable set to \e true if this shortcut may be configured by the user, otherwise \e false. 0362 */ 0363 void setShortcutConfigurable(bool configurable); 0364 0365 /** 0366 * Get the global shortcut for this action, if one exists. Global shortcuts 0367 * allow your actions to respond to accellerators independently of the focused window. 0368 * Unlike regular shortcuts, the application's window does not need focus 0369 * for them to be activated. 0370 * 0371 * \param type the type of shortcut to be returned. Should both be specified, only the 0372 * active shortcut will be returned. Defaults to the active shortcut, 0373 * if one exists. 0374 * 0375 * \sa KGlobalAccel 0376 * \sa setGlobalShortcut() 0377 */ 0378 KShortcut globalShortcut(ShortcutTypes type = ActiveShortcut) const; 0379 0380 /** 0381 * Assign a global shortcut for this action. Global shortcuts 0382 * allow an action to respond to key shortcuts independently of the focused window, 0383 * i.e. the action will trigger if the keys were pressed no matter where in the X session. 0384 * 0385 * The action must have a per main component unique 0386 * objectName() to enable cross-application bookeeping. If the objectName() is empty this method will 0387 * do nothing, otherwise the isGlobalShortcutEnabled() property will be set to true and the 0388 * shortcut will be enabled. 0389 * It is mandatory that the objectName() doesn't change once isGlobalshortcutEnabled() 0390 * has become true. 0391 * 0392 * \note KActionCollection::insert(name, action) will set action's objectName to name so you often 0393 * don't have to set an objectName explicitly. 0394 * 0395 * When an action, identified by main component name and objectName(), is assigned 0396 * a global shortcut for the first time on a KDE installation the assignment will 0397 * be saved. The shortcut will then be restored every time setGlobalShortcut() is 0398 * called with @p loading == Autoloading. 0399 * 0400 * If you actually want to change the global shortcut you have to set 0401 * @p loading to NoAutoloading. The new shortcut will be automatically saved again. 0402 * 0403 * \param shortcut global shortcut(s) to assign. Will be ignored unless \p loading is set to NoAutoloading or this is the first time ever you call this method (see above). 0404 * \param type the type of shortcut to be set, whether the active shortcut, the default shortcut, 0405 * or both (the default). 0406 * \param loading if Autoloading, assign the global shortcut this action has previously had if any. 0407 * That way user preferences and changes made to avoid clashes will be conserved. 0408 * if NoAutoloading the given shortcut will be assigned without looking up old values. 0409 * You should only do this if the user wants to change the shortcut or if you have 0410 * another very good reason. Key combinations that clash with other shortcuts will be 0411 * dropped. 0412 * 0413 * \note the default shortcut will never be influenced by autoloading - it will be set as given. 0414 * \sa globalShortcut() 0415 */ 0416 void setGlobalShortcut(const KShortcut &shortcut, ShortcutTypes type = 0417 ShortcutTypes(ActiveShortcut | DefaultShortcut), 0418 GlobalShortcutLoading loading = Autoloading); 0419 0420 /** 0421 * Returns true if this action is permitted to have a global shortcut. 0422 * Defaults to false. 0423 * Use isGlobalShortcutEnabled() instead. 0424 */ 0425 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED 0426 KDELIBS4SUPPORT_DEPRECATED bool globalShortcutAllowed() const; 0427 #endif 0428 0429 /** 0430 * Indicate whether the programmer and/or user may define a global shortcut for this action. 0431 * Defaults to false. Note that calling setGlobalShortcut() turns this on automatically. 0432 * 0433 * \param allowed set to \e true if this action may have a global shortcut, otherwise \e false. 0434 * \param loading if Autoloading, assign to this action the global shortcut it has previously had 0435 * if any. 0436 */ 0437 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED 0438 KDELIBS4SUPPORT_DEPRECATED void setGlobalShortcutAllowed(bool allowed, GlobalShortcutLoading loading = Autoloading); 0439 #endif 0440 0441 /** 0442 * Returns true if this action is enabled to have a global shortcut. 0443 * This will be respected by \class KGlobalShortcutsEditor. 0444 * Defaults to false. 0445 */ 0446 bool isGlobalShortcutEnabled() const; 0447 0448 /** 0449 * Sets the globalShortcutEnabled property to false and sets the global shortcut to an 0450 * empty shortcut. 0451 * This will also wipe out knowlegde about the existence of this action's global shortcut 0452 * so it will not be considered anymore for shortcut conflict resolution. It will also not be 0453 * visible anymore in the shortcuts KControl module. 0454 * This method should not be used unless these effects are explicitly desired. 0455 * @since 4.1 0456 */ 0457 void forgetGlobalShortcut(); 0458 0459 KShapeGesture shapeGesture(ShortcutTypes type = ActiveShortcut) const; 0460 KRockerGesture rockerGesture(ShortcutTypes type = ActiveShortcut) const; 0461 0462 void setShapeGesture(const KShapeGesture &gest, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut)); 0463 void setRockerGesture(const KRockerGesture &gest, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut)); 0464 0465 /** 0466 * Returns the action object associated with this action, or 0 if it does not have one 0467 * 0468 * @returns the KAuth::Action associated with this action. 0469 */ 0470 KAuth::Action authAction() const; 0471 0472 /** 0473 * Sets the action object associated with this action 0474 * 0475 * By setting a KAuth::Action, this action will become associated with it, and 0476 * whenever it gets clicked, it will trigger the authorization and execution process 0477 * for the action. The signal activated will also be emitted whenever the action gets 0478 * clicked and the action gets authorized. Pass 0 to this function to disassociate the action 0479 * 0480 * @param action the KAuth::Action to associate with this action. 0481 */ 0482 void setAuthAction(const KAuth::Action &action); 0483 0484 /** 0485 * Sets the action object associated with this action 0486 * 0487 * Overloaded member to allow creating the action by name 0488 * 0489 * @param actionName the name of the action to associate 0490 */ 0491 void setAuthAction(const QString &actionName); 0492 0493 Q_SIGNALS: 0494 #ifdef KDE3_SUPPORT 0495 /** 0496 * Emitted when this action is activated 0497 * 0498 * \deprecated use triggered(bool checked) instead. 0499 */ 0500 QT_MOC_COMPAT void activated(); 0501 #endif 0502 0503 /** 0504 * Emitted when the action is triggered. Also provides the state of the 0505 * keyboard modifiers and mouse buttons at the time. 0506 * @deprecated since 5.0, use triggered() signal from QAction and check for 0507 * QApplication::mouseButtons() and QApplication::keyboardModifiers() in the slot. 0508 */ 0509 void triggered(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers); 0510 0511 /** 0512 * Signal emitted when the action is triggered and authorized 0513 * 0514 * If the action needs authorization, when the user triggers the action, 0515 * the authorization process automatically begins. 0516 * If it succeeds, this signal is emitted. The KAuth::Action object is provided for convenience 0517 * if you have multiple KAuthorizedAction objects, but of course it's always the same set with 0518 * setAuthAction(). 0519 * 0520 * WARNING: If your action needs authorization you should connect eventual slots processing 0521 * stuff to this signal, and NOT triggered. Triggered will be emitted even if the user has not 0522 * been authorized 0523 * 0524 * @param action The object set with setAuthAction() 0525 */ 0526 void authorized(const KAuth::Action &action); 0527 0528 /** 0529 * Emitted when the global shortcut is changed. A global shortcut is 0530 * subject to be changed by the global shortcuts kcm. 0531 * @deprecated use KGlobalAccel::globalShortcutChanged instead 0532 */ 0533 void globalShortcutChanged(const QKeySequence &); 0534 0535 private: 0536 friend class KGlobalAccelPrivate; // Needs access to the component 0537 friend class KActionCollectionPrivate; // Needs access to the component 0538 friend class KShortcutsEditorDelegate; // Needs access to the component 0539 Q_PRIVATE_SLOT(d, void slotTriggered()) 0540 Q_PRIVATE_SLOT(d, void _k_emitActionGlobalShortcutChanged(QAction *, const QKeySequence &)) 0541 class KActionPrivate *const d; 0542 friend class KActionPrivate; 0543 friend class KGlobalShortcutTest; 0544 }; 0545 0546 Q_DECLARE_OPERATORS_FOR_FLAGS(KAction::ShortcutTypes) 0547 0548 #endif