1 /* 2 * %kadu copyright begin% 3 * Copyright 2010, 2011 Piotr Galiszewski (piotr.galiszewski@kadu.im) 4 * Copyright 2014 Piotr Dąbrowski (ultr@ultr.pl) 5 * Copyright 2010, 2011, 2014 Bartosz Brachaczek (b.brachaczek@gmail.com) 6 * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com) 7 * %kadu copyright end% 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 21 */ 22 23 #ifndef ACTION_DESCRIPTION_H 24 #define ACTION_DESCRIPTION_H 25 26 #include <QtCore/QMap> 27 #include <QtCore/QObject> 28 #include <QtCore/QPointer> 29 #include <QtWidgets/QToolButton> 30 #include <functional> 31 #include <injeqt/injeqt.h> 32 33 #include "configuration/configuration-aware-object.h" 34 #include "icons/kadu-icon.h" 35 36 class QAction; 37 class QMenu; 38 39 class ActionContext; 40 class Actions; 41 class Action; 42 class Configuration; 43 class InjectedFactory; 44 45 using ActionBoolCallback = std::function<void(Action *)>; 46 47 /** 48 * @addtogroup Actions 49 * @{ 50 */ 51 52 /** 53 * @class ActionDescription 54 * @author Rafał 'Vogel' Malinowski 55 * @short Class responsible for describing and creating actions for windows. 56 * 57 * This class is used to describe actions that can be created and inserted into menus and 58 * toolbars on different types of windows. Some actions can be only used in connection with 59 * chats, users, search window or history window. Some actions are only useable in main 60 * menu of Kadu. 61 * 62 * For each action each window gets its own instance of Action class created by given ActionDescription 63 * object. This is required because each window contains different objects (like chats, contacts and 64 * buddies) and may have different conditions for enabling/disabling actions. Windows are mapped 65 * as ActionContext interfaces - each type of window or widget can have its own implementation 66 * of this interface. 67 * 68 * Actions can be simple actions or actions with menu. If action has menu, it has to implement 69 * menuForAction method. Each menuForAction must return different instance of menu, as this method is called 70 * only once for each Action and menu will be destroyed when Action is destroyed. 71 * 72 * ActionDescription has two constructors. One of them is public and has a lot ofparameters. This 73 * is depreceated and will be removed in 0.11.0 or 0.12.0 release. This constructor registers action 74 * automatically. 75 * 76 * Second constructor is protected and had only one parameter - parent. This one should be called 77 * by subclasses. Then all setXXX methods should be called to set up proper values of ActionDescription 78 * properties. After setting all values registerAction method must be called so action can be used 79 * on toolbars in menus. Do not call registerAction before setting all properties. 80 * 81 * Unregistering of action is automatically performed by destructor. 82 */ 83 class KADUAPI ActionDescription : public QObject, protected ConfigurationAwareObject 84 { 85 Q_OBJECT 86 87 public: 88 89 enum ActionType { 90 TypeGlobal = 0x0001, //!< actions with TypeGlobal type does not require access to user list or anything window-dependent 91 TypeUser = 0x0002, //!< actions with TypeUser type requires access to one or more users from user list 92 TypeChat = 0x0004, //!< actions with TypeChat type requires access to chat window 93 TypeSearch = 0x0008, //!< actions with TypeSearch type requires access to search window 94 TypeUserList = 0x0010, //!< actions with TypeUserList type requires access to user list widget 95 TypeHistory = 0x0020, //!< actions with TypeHistory type requires access to history window 96 TypeMainMenu = 0x0040, 97 TypePrivate = 0x0080, //!< actions with TypePrivate can not be placed on toolbars by users 98 TypeAll = 0xFFFF //!< TypeAll is used to set masks for all types of actions 99 }; 100 101 private: 102 friend class Action; 103 104 QPointer<Actions> m_actions; 105 QPointer<Configuration> m_configuration; 106 QPointer<InjectedFactory> m_injectedFactory; 107 bool m_selfRegister; 108 109 QMap<ActionContext *, Action *> MappedActions; 110 bool Deleting; 111 112 ActionType Type; 113 QString Name; 114 QObject *Object; 115 const char *Slot; 116 KaduIcon Icon; 117 QString Text; 118 bool Checkable; 119 ActionBoolCallback EnableCallback; 120 QString ShortcutItem; 121 Qt::ShortcutContext ShortcutContext; 122 123 private slots: 124 INJEQT_SET void setActions(Actions *actions); 125 INJEQT_SET void setConfiguration(Configuration *configuration); 126 INJEQT_SET void setInjectedFactory(InjectedFactory *injectedFactory); 127 INJEQT_INIT void init(); 128 129 void actionAboutToBeDestroyed(Action *action); 130 void actionTriggeredSlot(QAction *sender, bool toggled); 131 132 protected: 133 Configuration * configuration() const; 134 InjectedFactory * injectedFactory() const; 135 136 /** 137 * @author Rafał 'Vogel' Malinowski 138 * @short Creates new instance of ActionDescription with given parent. 139 * @param parent QObject parent of ActionDescription. 140 * 141 * Created new empty instance of ActionDescription. Call setters and registerActions to 142 * make this action description useable. 143 */ 144 ActionDescription(QObject *parent); 145 146 Actions * actionsRegistry() const; 147 148 /** 149 * @author Rafał 'Vogel' Malinowski 150 * @short Registers this action in global action list. 151 * 152 * Registers this action in global action list. Called automatically by depreceated public 153 * constructor. In new implementation this should be called from subclasses after all apprioprate 154 * setters were called. 155 */ 156 void registerAction(Actions *actions); 157 158 /** 159 * @author Rafał 'Vogel' Malinowski 160 * @short Unregisters this action from global action list. 161 * 162 * Registers this action from global action list. Called automatically by destructor. No need to call 163 * this manually. 164 */ 165 void unregisterAction(Actions *actions); 166 167 /** 168 * @author Rafał 'Vogel' Malinowski 169 * @todo rename to actionCreated after actionCreated slot is removed 170 * @short Called when new instance of Action is created. 171 * @param action newly created action 172 * 173 * This method is called automatically when new instance of Action is created. It allows to set uo 174 * additional Action parameters. 175 * 176 * By defult this method checks if this instance of Actions should have menu attached and creates it 177 * if needed (see menuForAction). 178 * 179 * Old implementations of actions uses actionCreated signal that is now depreceated. 180 */ 181 virtual void actionInstanceCreated(Action *action); 182 183 /** 184 * @author Rafał 'Vogel' Malinowski 185 * @todo make abstract when actions are moved to new API 186 * @short Called when instance of Action is triggered. 187 * @param sender instance of QAction that was triggered 188 * @param toggled true, if action was toggled on 189 * 190 * This method is called automatically when instance of QAction is triggered. 191 * 192 * By defult this method does nothing. 193 * 194 * Old implementations of actions uses object and slot parameters in constructor to get notification 195 * about action triggering. 196 */ actionTriggered(QAction * sender,bool toggled)197 virtual void actionTriggered(QAction *sender, bool toggled) 198 { 199 Q_UNUSED(sender) 200 Q_UNUSED(toggled) 201 } 202 203 /** 204 * @author Rafał 'Vogel' Malinowski 205 * @todo make abstract when actions are moved to new API 206 * @short Called when instance of Action is triggered. 207 * @param widget parent widget of triggered action 208 * @param context context of triggered action 209 * @param toggled true, if action was toggled on 210 * 211 * This method is called automatically when instance of QAction is triggered. 212 * 213 * By defult this method does nothing. 214 * 215 * Old implementations of actions uses object and slot parameters in constructor to get notification 216 * about action triggering. 217 */ triggered(QWidget * widget,ActionContext * context,bool toggled)218 virtual void triggered(QWidget *widget, ActionContext *context, bool toggled) 219 { 220 Q_UNUSED(widget) 221 Q_UNUSED(context) 222 Q_UNUSED(toggled) 223 } 224 225 /** 226 * @author Rafał 'Vogel' Malinowski 227 * @short Updates enabled/disabled state of given action. 228 * @param action action to update state for 229 * 230 * This method is called by by Action class when it requies to update its own state (like disabled/enable). 231 * By defult this method calls EnableCallback callback for this action. 232 */ 233 virtual void updateActionState(Action *action); 234 235 /** 236 * @author Rafał 'Vogel' Malinowski 237 * @short Creates menu for given new instance of Action. 238 * @param action action to create menu for 239 * 240 * This method is called by default implementation of actionInstanceCreated. This method should 241 * return null when no menu for given action is required. New instance of QMenu should be returned 242 * when this actions requires menu. Please note that Action takes ownership of this QMenu instance 243 * and can delete it at any moment. 244 * 245 * By defult this method returns null. 246 */ 247 virtual QMenu * menuForAction(Action *action); 248 249 virtual void connectNotify(const QMetaMethod &signal); 250 virtual void configurationUpdated(); 251 252 public: 253 /** 254 * @author Rafał 'Vogel' Malinowski 255 * @short Depreceated contructor. 256 * 257 * Depreceated contructor. 258 */ 259 ActionDescription(QObject *parent, ActionType type, const QString &name, QObject *object, const char *slot, 260 const KaduIcon &icon, const QString &text, bool checkable = false, ActionBoolCallback enableCallback = 0); 261 virtual ~ActionDescription(); 262 263 /** 264 * @author Rafał 'Vogel' Malinowski 265 * @short Creates instance of Action for given ActionContext. 266 * @param context context of new Action instance 267 * @param parent parent of new Action instance 268 * 269 * This method creates new instance of Action for given ActionContext or returns existing one, if action for 270 * given ActionContext was already created. Each ActionContext will have different instance of Actions. 271 * 272 * This method calls actionInstanceCreated and emits actionCreated if new instance were created. 273 */ 274 Action * createAction(ActionContext *context, QObject *parent); 275 276 /** 277 * @author Rafał 'Vogel' Malinowski 278 * @short Returns list of all Actions created from this ActionDescription. 279 * 280 * Returns list of all Actions created from this ActionDescription. 281 */ 282 QList<Action *> actions(); 283 284 /** 285 * @author Rafał 'Vogel' Malinowski 286 * @short Returns Action instance connected with given ActionContext. 287 * @param context ActionContext to search Action for 288 * 289 * Returns Action instance connected with given ActionContext or 0 when no Action was created. 290 */ 291 Action * action(ActionContext *context); 292 293 void setType(ActionType type); 294 void setName(const QString &name); 295 void setConnection(QObject *object, const char *slot); 296 void setIcon(const KaduIcon &icon); 297 void setText(const QString &text); 298 void setCheckable(bool checkable); 299 void setActionCallback(ActionBoolCallback enableCallback); 300 type()301 ActionType type() const { return Type; } name()302 const QString & name() const { return Name; } icon()303 const KaduIcon & icon() const { return Icon; } text()304 const QString & text() const { return Text; } isCheckable()305 bool isCheckable() const { return Checkable; } 306 307 void setShortcut(QString configItem, Qt::ShortcutContext context = Qt::WindowShortcut); 308 309 /** 310 * @author Rafał 'Vogel' Malinowski 311 * @short Returns QToolButton::ToolButtonPopupMode for given action. 312 * 313 * Returns QToolButton::ToolButtonPopupMode for given action. This allows actions with menu that 314 * can have default behavior or not. By default actions have default behavior - QToolButton::MenuButtonPopup 315 * is returned. 316 * 317 * If action does not have default behavior no method will be called after clicking on method. Reimplementing 318 * actionTriggered is then not required. 319 */ buttonPopupMode()320 virtual QToolButton::ToolButtonPopupMode buttonPopupMode() const 321 { 322 return QToolButton::MenuButtonPopup; 323 } 324 325 /** 326 * @short Updates states of all actions of this type. 327 */ 328 void updateActionStates(); 329 330 signals: 331 void actionCreated(Action *); 332 333 }; 334 335 /** 336 * @} 337 */ 338 339 #endif // ACTION_DESCRIPTION_H 340