| 1 | /* |
| 2 | This file is part of the KDE libraries |
| 3 | SPDX-FileCopyrightText: 1999 Reginald Stadlbauer <reggie@kde.org> |
| 4 | SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org> |
| 5 | SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org> |
| 6 | SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org> |
| 7 | SPDX-FileCopyrightText: 2000 Michael Koch <koch@kde.org> |
| 8 | SPDX-FileCopyrightText: 2001 Holger Freyther <freyther@kde.org> |
| 9 | SPDX-FileCopyrightText: 2002 Ellis Whitehead <ellis@kde.org> |
| 10 | SPDX-FileCopyrightText: 2003 Andras Mantia <amantia@kde.org> |
| 11 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org> |
| 12 | SPDX-FileCopyrightText: 2006 Albert Astals Cid <aacid@kde.org> |
| 13 | SPDX-FileCopyrightText: 2006 Clarence Dang <dang@kde.org> |
| 14 | SPDX-FileCopyrightText: 2006 Michel Hermier <michel.hermier@gmail.com> |
| 15 | SPDX-FileCopyrightText: 2007 Nick Shaforostoff <shafff@ukr.net> |
| 16 | |
| 17 | SPDX-License-Identifier: LGPL-2.0-only |
| 18 | */ |
| 19 | |
| 20 | #ifndef KSELECTACTION_H |
| 21 | #define KSELECTACTION_H |
| 22 | |
| 23 | #include <QToolButton> |
| 24 | #include <QWidgetAction> |
| 25 | #include <memory> |
| 26 | |
| 27 | #include <kwidgetsaddons_export.h> |
| 28 | |
| 29 | class KSelectActionPrivate; |
| 30 | |
| 31 | /*! |
| 32 | * \class KSelectAction |
| 33 | * \inmodule KWidgetsAddons |
| 34 | * |
| 35 | * \brief Action for selecting one of several items. |
| 36 | * |
| 37 | * Action for selecting one of several items. |
| 38 | * |
| 39 | * This action shows up a submenu with a list of items. |
| 40 | * One of them can be checked. If the user clicks on an item |
| 41 | * this item will automatically be checked, |
| 42 | * the formerly checked item becomes unchecked. |
| 43 | * There can be only one item checked at a time. |
| 44 | * |
| 45 | * Porting from KF5 to KF6: |
| 46 | * |
| 47 | * The overloaded signal KSelectAction::triggered(QAction *action) was renamed |
| 48 | * to KSelectAction::actionTriggered(QAction *action). |
| 49 | * |
| 50 | * The protected virtual method KSelectAction::actionTriggered(QAction *action) was renamed |
| 51 | * to KSelectAction::slotActionTriggered(QAction *action). |
| 52 | */ |
| 53 | class KWIDGETSADDONS_EXPORT KSelectAction : public QWidgetAction |
| 54 | { |
| 55 | Q_OBJECT |
| 56 | |
| 57 | /*! |
| 58 | * \property KSelectAction::currentAction |
| 59 | */ |
| 60 | Q_PROPERTY(QAction *currentAction READ currentAction WRITE setCurrentAction) |
| 61 | |
| 62 | /*! |
| 63 | * \property KSelectAction::editable |
| 64 | */ |
| 65 | Q_PROPERTY(bool editable READ isEditable WRITE setEditable) |
| 66 | |
| 67 | /*! |
| 68 | * \property KSelectAction::comboWidth |
| 69 | */ |
| 70 | Q_PROPERTY(int comboWidth READ comboWidth WRITE setComboWidth) |
| 71 | |
| 72 | /*! |
| 73 | * \property KSelectAction::currentText |
| 74 | */ |
| 75 | Q_PROPERTY(QString currentText READ currentText) |
| 76 | |
| 77 | /*! |
| 78 | * \property KSelectAction::toolBarMode |
| 79 | */ |
| 80 | Q_PROPERTY(ToolBarMode toolBarMode READ toolBarMode WRITE setToolBarMode) |
| 81 | |
| 82 | /*! |
| 83 | * \property KSelectAction::toolButtonPopupMode |
| 84 | */ |
| 85 | Q_PROPERTY(QToolButton::ToolButtonPopupMode toolButtonPopupMode READ toolButtonPopupMode WRITE setToolButtonPopupMode) |
| 86 | |
| 87 | /*! |
| 88 | * \property KSelectAction::currentItem |
| 89 | */ |
| 90 | Q_PROPERTY(int currentItem READ currentItem WRITE setCurrentItem) |
| 91 | |
| 92 | /*! |
| 93 | * \property KSelectAction::items |
| 94 | */ |
| 95 | Q_PROPERTY(QStringList items READ items WRITE setItems) |
| 96 | |
| 97 | public: |
| 98 | /*! |
| 99 | * Constructs a selection action with the specified parent. |
| 100 | * |
| 101 | * \a parent The action's parent object. |
| 102 | */ |
| 103 | explicit KSelectAction(QObject *parent); |
| 104 | |
| 105 | /*! |
| 106 | * Constructs a selection action with text; a shortcut may be specified by |
| 107 | * the ampersand character (e.g.\ "&Option" creates a shortcut with key \c O ) |
| 108 | * |
| 109 | * This is the most common KSelectAction used when you do not have a |
| 110 | * corresponding icon (note that it won't appear in the current version |
| 111 | * of the "Edit ToolBar" dialog, because an action needs an icon to be |
| 112 | * plugged in a toolbar...). |
| 113 | * |
| 114 | * \a text The text that will be displayed. |
| 115 | * |
| 116 | * \a parent The action's parent object. |
| 117 | */ |
| 118 | KSelectAction(const QString &text, QObject *parent); |
| 119 | |
| 120 | /*! |
| 121 | * Constructs a selection action with text and an icon; a shortcut may be specified by |
| 122 | * the ampersand character (e.g.\ "&Option" creates a shortcut with key \c O ) |
| 123 | * |
| 124 | * This is the other common KSelectAction used. Use it when you |
| 125 | * do have a corresponding icon. |
| 126 | * |
| 127 | * \a icon The icon to display. |
| 128 | * |
| 129 | * \a text The text that will be displayed. |
| 130 | * |
| 131 | * \a parent The action's parent object. |
| 132 | */ |
| 133 | KSelectAction(const QIcon &icon, const QString &text, QObject *parent); |
| 134 | |
| 135 | ~KSelectAction() override; |
| 136 | |
| 137 | /*! |
| 138 | * \value MenuMode Creates a button which pops up a menu when interacted with, as defined by toolButtonPopupMode(). |
| 139 | * \value Creates a combo box which contains the actions. This is the default. |
| 140 | */ |
| 141 | enum ToolBarMode { |
| 142 | , |
| 143 | ComboBoxMode, |
| 144 | }; |
| 145 | Q_ENUM(ToolBarMode) |
| 146 | |
| 147 | /*! |
| 148 | * Returns which type of widget (combo box or button with drop-down menu) will be inserted |
| 149 | * in a toolbar. |
| 150 | */ |
| 151 | ToolBarMode toolBarMode() const; |
| 152 | |
| 153 | /*! |
| 154 | * Set the type of widget to be inserted in a toolbar to \a mode. |
| 155 | */ |
| 156 | void setToolBarMode(ToolBarMode mode); |
| 157 | |
| 158 | /*! |
| 159 | * Returns the style for the list of actions, when this action is plugged |
| 160 | * into a KToolBar. The default value is QToolButton::InstantPopup |
| 161 | * |
| 162 | * \sa QToolButton::setPopupMode() |
| 163 | */ |
| 164 | QToolButton::ToolButtonPopupMode () const; |
| 165 | |
| 166 | /*! |
| 167 | * Set how this list of actions should behave when in popup mode and plugged into a toolbar. |
| 168 | */ |
| 169 | void (QToolButton::ToolButtonPopupMode mode); |
| 170 | |
| 171 | /*! |
| 172 | * The action group used to create exclusivity between the actions associated with this action. |
| 173 | */ |
| 174 | QActionGroup *selectableActionGroup() const; |
| 175 | |
| 176 | /*! |
| 177 | * Returns the current QAction. |
| 178 | * \sa setCurrentAction |
| 179 | */ |
| 180 | QAction *currentAction() const; |
| 181 | |
| 182 | /*! |
| 183 | * Returns the index of the current item. |
| 184 | * |
| 185 | * \sa currentText(), currentAction() |
| 186 | */ |
| 187 | int currentItem() const; |
| 188 | |
| 189 | /*! |
| 190 | * Returns the text of the currently selected item. |
| 191 | * |
| 192 | * \sa currentItem(), currentAction() |
| 193 | */ |
| 194 | QString currentText() const; |
| 195 | |
| 196 | /*! |
| 197 | * Returns the list of selectable actions |
| 198 | */ |
| 199 | QList<QAction *> actions() const; |
| 200 | |
| 201 | /*! |
| 202 | * Returns the action at \a index, if one exists. |
| 203 | */ |
| 204 | QAction *action(int index) const; |
| 205 | |
| 206 | /*! |
| 207 | * Searches for an action with the specified \a text, using a search whose |
| 208 | * case sensitivity is defined by \a cs. |
| 209 | */ |
| 210 | QAction *action(const QString &text, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; |
| 211 | |
| 212 | /*! |
| 213 | * Sets the currently checked item. |
| 214 | * |
| 215 | * \a action the QAction to become the currently checked item. |
| 216 | * |
| 217 | * Returns \c true if a corresponding action was found and successfully checked. |
| 218 | */ |
| 219 | bool setCurrentAction(QAction *action); |
| 220 | |
| 221 | /*! |
| 222 | * Convenience function to set the currently checked action to be the action |
| 223 | * at index \a index. |
| 224 | * |
| 225 | * If there is no action at that index, the currently checked action (if any) will |
| 226 | * be deselected. |
| 227 | * |
| 228 | * Returns \c true if a corresponding action was found and thus set to the current action, otherwise \e false |
| 229 | */ |
| 230 | bool setCurrentItem(int index); |
| 231 | |
| 232 | /*! |
| 233 | * Overloaded member function, provided for convenience, to set the currently |
| 234 | * checked action to be the action which has \a text as its text(). |
| 235 | * |
| 236 | * If there is no action at that index, the currently checked action (if any) will |
| 237 | * be deselected. |
| 238 | * |
| 239 | * Returns \c true if a corresponding action was found, otherwise \c false |
| 240 | */ |
| 241 | bool setCurrentAction(const QString &text, Qt::CaseSensitivity cs = Qt::CaseSensitive); |
| 242 | |
| 243 | /*! |
| 244 | * Add \a action to the list of selectable actions. |
| 245 | */ |
| 246 | void addAction(QAction *action); |
| 247 | |
| 248 | /*! |
| 249 | * Overloaded member function, provided for convenience, which creates an action |
| 250 | * from \a text and inserts it into the list of selectable actions. |
| 251 | * |
| 252 | * The newly created action is checkable and not user configurable. |
| 253 | */ |
| 254 | QAction *addAction(const QString &text); |
| 255 | |
| 256 | /*! |
| 257 | * Overloaded member function, provided for convenience, which creates an action |
| 258 | * from \a text and \a icon and inserts it into the list of selectable actions. |
| 259 | * |
| 260 | * The newly created action is checkable and not user configurable. |
| 261 | */ |
| 262 | QAction *addAction(const QIcon &icon, const QString &text); |
| 263 | |
| 264 | /*! |
| 265 | * Remove the specified \a action from this action selector. |
| 266 | * |
| 267 | * You take ownership here, so save or delete it in order to not leak the action. |
| 268 | */ |
| 269 | virtual QAction *removeAction(QAction *action); |
| 270 | |
| 271 | /*! |
| 272 | * Inserts the action action to this widget's list of actions, before the action before. |
| 273 | * It appends the action if before is a null pointer or before is not a valid action for this widget. |
| 274 | * |
| 275 | * \since 5.0 |
| 276 | */ |
| 277 | virtual void insertAction(QAction *before, QAction *action); |
| 278 | |
| 279 | /*! |
| 280 | * Convenience function to create the list of selectable items. |
| 281 | * |
| 282 | * Any previously existing items will be cleared. |
| 283 | */ |
| 284 | void setItems(const QStringList &lst); |
| 285 | |
| 286 | /*! |
| 287 | * Convenience function which returns the items that can be selected with this action. |
| 288 | * |
| 289 | * It is the same as iterating selectableActionGroup()->actions() and looking at each |
| 290 | * action's text(). |
| 291 | */ |
| 292 | QStringList items() const; |
| 293 | |
| 294 | /*! |
| 295 | * When this action is plugged into a toolbar, it creates a combobox. |
| 296 | * |
| 297 | * Returns \c true if the combo editable. |
| 298 | */ |
| 299 | bool isEditable() const; |
| 300 | |
| 301 | /*! |
| 302 | * When this action is plugged into a toolbar, it creates a combobox. |
| 303 | * |
| 304 | * This makes the combo editable or read-only. |
| 305 | */ |
| 306 | void setEditable(bool); |
| 307 | |
| 308 | /*! |
| 309 | * When this action is plugged into a toolbar, it creates a combobox. |
| 310 | * |
| 311 | * This returns the maximum width set by setComboWidth |
| 312 | */ |
| 313 | int comboWidth() const; |
| 314 | |
| 315 | /*! |
| 316 | * When this action is plugged into a toolbar, it creates a combobox. |
| 317 | * |
| 318 | * This gives a _maximum_ size to the combobox. |
| 319 | * |
| 320 | * The minimum size is automatically given by the contents (the items). |
| 321 | */ |
| 322 | void setComboWidth(int width); |
| 323 | |
| 324 | /*! |
| 325 | * Sets the maximum items that are visible at once if the action |
| 326 | * is a combobox, that is the number of items in the combobox's viewport |
| 327 | */ |
| 328 | void setMaxComboViewCount(int n); |
| 329 | |
| 330 | /*! |
| 331 | * Remove and delete all the items in this action. |
| 332 | * |
| 333 | * \sa removeAllActions() |
| 334 | */ |
| 335 | void clear(); |
| 336 | |
| 337 | /*! |
| 338 | * Remove all the items in this action. |
| 339 | * |
| 340 | * Unlike clear(), this will not delete the actions. |
| 341 | * |
| 342 | * \sa clear() |
| 343 | */ |
| 344 | void removeAllActions(); |
| 345 | |
| 346 | /*! |
| 347 | * Sets whether any occurrence of the ampersand character ( & ) in items |
| 348 | * should be interpreted as keyboard accelerator for items displayed in a |
| 349 | * menu or not. Only applies to (overloaded) methods dealing with QStrings, |
| 350 | * not those dealing with QActions. |
| 351 | * |
| 352 | * Defaults to true. |
| 353 | * |
| 354 | * \a b true if ampersands indicate a keyboard accelerator, otherwise false. |
| 355 | */ |
| 356 | void (bool b); |
| 357 | |
| 358 | /*! |
| 359 | * Returns whether ampersands passed to methods using QStrings are interpreted |
| 360 | * as keyboard accelerator indicators or as literal ampersands. |
| 361 | */ |
| 362 | bool () const; |
| 363 | |
| 364 | /*! |
| 365 | * You should delete KSelectAction::menu() before calling setMenu(). KSelectAction |
| 366 | * will take the \a menu ownership and it will be deleted when KSelectAction is |
| 367 | * destroyed. |
| 368 | */ |
| 369 | using QWidgetAction::setMenu; |
| 370 | |
| 371 | /*! |
| 372 | * Changes the text of item \a index to \a text . |
| 373 | */ |
| 374 | void changeItem(int index, const QString &text); |
| 375 | |
| 376 | Q_SIGNALS: |
| 377 | /*! |
| 378 | * This signal is emitted when an item is selected. |
| 379 | * |
| 380 | * \a action indicates the item selected |
| 381 | * |
| 382 | * \since 6.0 |
| 383 | */ |
| 384 | void actionTriggered(QAction *action); |
| 385 | |
| 386 | /*! |
| 387 | * This signal is emitted when an item is selected. |
| 388 | * |
| 389 | * \a index indicates the item selected |
| 390 | * |
| 391 | * \since 5.78 |
| 392 | */ |
| 393 | void indexTriggered(int index); |
| 394 | |
| 395 | /*! |
| 396 | * This signal is emitted when an item is selected. |
| 397 | * |
| 398 | * \a text indicates the item selected |
| 399 | * |
| 400 | * \since 5.78 |
| 401 | */ |
| 402 | void textTriggered(const QString &text); |
| 403 | |
| 404 | protected Q_SLOTS: |
| 405 | /*! |
| 406 | * This function is called whenever an action from the selections is triggered. |
| 407 | * The default implementation calls trigger() if isCheckable() is \c true, then emits |
| 408 | * the signals actionTriggered(QAction *), indexTriggered(int) and textTriggered(const QString &). |
| 409 | * |
| 410 | * \since 6.0 |
| 411 | */ |
| 412 | virtual void slotActionTriggered(QAction *action); |
| 413 | |
| 414 | /*! |
| 415 | * For structured menu building. Deselects all items if the action was unchecked by the top menu |
| 416 | */ |
| 417 | void slotToggled(bool); |
| 418 | |
| 419 | protected: |
| 420 | QWidget *createWidget(QWidget *parent) override; |
| 421 | |
| 422 | void deleteWidget(QWidget *widget) override; |
| 423 | |
| 424 | bool event(QEvent *event) override; |
| 425 | |
| 426 | bool eventFilter(QObject *watched, QEvent *event) override; |
| 427 | |
| 428 | KWIDGETSADDONS_NO_EXPORT KSelectAction(KSelectActionPrivate &dd, QObject *parent); |
| 429 | |
| 430 | std::unique_ptr<class KSelectActionPrivate> const d_ptr; |
| 431 | |
| 432 | private: |
| 433 | Q_DECLARE_PRIVATE(KSelectAction) |
| 434 | }; |
| 435 | |
| 436 | #endif |
| 437 | |