1 /*
2     This file is part of the KDE project
3     SPDX-FileCopyrightText: 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
4 
5     SPDX-License-Identifier: LGPL-2.0-only
6 */
7 
8 #ifndef _KACTION_SELECTOR_H_
9 #define _KACTION_SELECTOR_H_
10 
11 #include <QWidget>
12 #include <kwidgetsaddons_export.h>
13 #include <memory>
14 
15 class QListWidget;
16 class QListWidgetItem;
17 class QKeyEvent;
18 class QEvent;
19 class QIcon;
20 
21 /**
22     @class KActionSelector kactionselector.h KActionSelector
23 
24     @short A widget for selecting and arranging actions/objects
25 
26     This widget allows the user to select from a set of objects and arrange
27     the order of the selected ones using two list boxes labeled "Available"
28     and "Used" with horizontal arrows in between to move selected objects between
29     the two, and vertical arrows on the right to arrange the order of the selected
30     objects.
31 
32     The widget moves objects to the other listbox when doubleclicked if
33     the property moveOnDoubleClick is set to true (default). See moveOnDoubleClick()
34     and setMoveOnDoubleClick().
35 
36     The user control the widget using the keyboard if enabled (default),
37     see keyboardEnabled.
38 
39     Note that this may conflict with keyboard selection in the selected list box,
40     if you set that to anything else than QListWidget::Single (which is the default).
41 
42     To use it, simply construct an instance and then add items to the two listboxes,
43     available through lbAvailable() and lbSelected(). Whenever you want, you can retrieve
44     the selected options using QListWidget methods on lbSelected().
45 
46     This way, you can use your own QListWidgetItem class, allowing you to easily
47     store object data in those.
48 
49     When an item is moved to a listbox, it is placed below the current item
50     of that listbox.
51 
52     Standard arrow icons are used, but you can use icons of your own choice if desired,
53     see setButtonIcon(). It is also possible to set tooltips and whatsthis help
54     for the buttons. See setButtonTooltip() and setButtonWhatsThis().
55 
56     To set whatsthis or tooltips for the listboxes, access them through
57     availableListWidget() and selectedListWidget().
58 
59     All the moving buttons are automatically set enabled as expected.
60 
61     Signals are sent each time an item is moved, allowing you to follow the
62     users actions if you need to. See addedToSelection(), removedFromSelection(),
63     movedUp() and movedDown()
64 
65     \image html kactionselector.png "KActionSelector Widget"
66 
67     @author Anders Lund <anders@alweb.dk>
68 */
69 class KWIDGETSADDONS_EXPORT KActionSelector : public QWidget
70 {
71     Q_OBJECT
72     Q_PROPERTY(bool moveOnDoubleClick READ moveOnDoubleClick WRITE setMoveOnDoubleClick)
73     Q_PROPERTY(bool keyboardEnabled READ keyboardEnabled WRITE setKeyboardEnabled)
74     Q_PROPERTY(QString availableLabel READ availableLabel WRITE setAvailableLabel)
75     Q_PROPERTY(QString selectedLabel READ selectedLabel WRITE setSelectedLabel)
76     Q_PROPERTY(InsertionPolicy availableInsertionPolicy READ availableInsertionPolicy WRITE setAvailableInsertionPolicy)
77     Q_PROPERTY(InsertionPolicy selectedInsertionPolicy READ selectedInsertionPolicy WRITE setSelectedInsertionPolicy)
78     Q_PROPERTY(bool showUpDownButtons READ showUpDownButtons WRITE setShowUpDownButtons)
79 
80 public:
81     explicit KActionSelector(QWidget *parent = nullptr);
82     ~KActionSelector() override;
83 
84     /**
85      * @return The QListWidget holding the available actions
86      */
87     QListWidget *availableListWidget() const;
88 
89     /**
90      * @return The QListWidget holding the selected actions
91      */
92     QListWidget *selectedListWidget() const;
93 
94     /**
95      * This enum identifies the moving buttons
96      */
97     enum MoveButton {
98         ButtonAdd,
99         ButtonRemove,
100         ButtonUp,
101         ButtonDown,
102     };
103     Q_ENUM(MoveButton)
104 
105     /**
106      * This enum defines policies for where to insert moved items in a listbox.
107      *
108      * @sa availableInsertionPolicy(), setAvailableInsertionPolicy(),
109      * selectedInsertionPolicy(), setSelectedInsertionPolicy()
110      */
111     enum InsertionPolicy {
112         BelowCurrent, ///< The item is inserted below the listbox' currentItem() or at the end if there is no current item.
113         Sorted, ///< The listbox is sort()ed after one or more items are inserted.
114         AtTop, ///< The item is inserted at index 0 in the listbox.
115         AtBottom, ///< The item is inserted at the end of the listbox.
116     };
117     Q_ENUM(InsertionPolicy)
118 
119     /**
120      * @return Whether moveOnDoubleClcik is enabled.
121      *
122      * If enabled, an item in any listbox will be moved to the other one whenever
123      * double-clicked.
124      * This feature is enabled by default.
125      * @sa setMoveOnDoubleClick()
126      */
127     bool moveOnDoubleClick() const;
128 
129     /**
130      * Sets moveOnDoubleClick to @p enable
131      * @sa moveOnDoubleClick()
132      */
133     void setMoveOnDoubleClick(bool enable);
134 
135     /**
136      * @return Whether keyboard control is enabled.
137      *
138      * When Keyboard control is enabled, the widget will react to
139      * the following keyboard actions:
140      * @li CTRL + Right - simulate clicking the add button
141      * @li CTRL + Left - simulate clicking the remove button
142      * @li CTRL + Up - simulate clicking the up button
143      * @li CTRL + Down - simulate clicking the down button
144      *
145      * Additionally, pressing RETURN or ENTER on one of the list boxes
146      * will cause the current item of that listbox to be moved to the other
147      * listbox.
148      *
149      * The keyboard actions are enabled by default.
150      *
151      * @sa setKeyboardEnabled()
152      */
153     bool keyboardEnabled() const;
154 
155     /**
156      * Sets the keyboard enabled depending on @p enable.
157      * @sa keyboardEnabled()
158      */
159     void setKeyboardEnabled(bool enable);
160 
161     /**
162      * @return The text of the label for the available items listbox.
163      */
164     QString availableLabel() const;
165 
166     /**
167      * Sets the label for the available items listbox to @p text.
168      * Note that this label has the listbox as its @e buddy, so that
169      * if you have a single ampersand in the text, the following character
170      * will become the accelerator to focus the listbox.
171      */
172     void setAvailableLabel(const QString &text);
173 
174     /**
175      * @return the label of the selected items listbox.
176      */
177     QString selectedLabel() const;
178 
179     /**
180      * Sets the label for the selected items listbox to @p text.
181      * Note that this label has the listbox as its @e buddy, so that
182      * if you have a single ampersand in the text, the following character
183      * will become the accelerator to focus the listbox.
184      */
185     void setSelectedLabel(const QString &text);
186 
187     /**
188      * @return The current insertion policy for the available listbox.
189      * The default policy for the available listbox is Sorted.
190      * @sa InsertionPolicy, setAvailableInsertionPolicy()
191      */
192     InsertionPolicy availableInsertionPolicy() const;
193 
194     /**
195      * Sets the insertion policy for the available listbox.
196      * @sa InsertionPolicy, availableInsertionPolicy()
197      */
198     void setAvailableInsertionPolicy(InsertionPolicy policy);
199 
200     /**
201      * @return The current insertion policy for the selected listbox.
202      * The default policy for the selected listbox is BelowCurrent.
203      * @sa InsertionPolicy, setSelectedInsertionPolicy()
204      */
205     InsertionPolicy selectedInsertionPolicy() const;
206 
207     /**
208      * Sets the insertion policy for the selected listbox.
209      * @sa InsertionPolicy, selectedInsertionPolicy()
210      */
211     void setSelectedInsertionPolicy(InsertionPolicy policy);
212 
213     /**
214      * @return whether the Up and Down buttons should be displayed.
215      */
216     bool showUpDownButtons() const;
217 
218     /**
219      * Sets whether the Up and Down buttons should be displayed
220      * according to @p show
221      */
222     void setShowUpDownButtons(bool show);
223 
224     /**
225      * Sets the pixmap of the button @p button to @p icon.
226      * It calls SmallIconSet(pm) to generate the icon set.
227      */
228     void setButtonIcon(const QString &icon, MoveButton button);
229 
230     /**
231      * Sets the iconset for button @p button to @p iconset.
232      * You can use this method to set a custom icon set. Either
233      * created by QIconSet, or use the application instance of
234      * KIconLoader (recommended).
235      */
236     void setButtonIconSet(const QIcon &iconset, MoveButton button);
237 
238     /**
239      * Sets the tooltip for the button @p button to @p tip.
240      */
241     void setButtonTooltip(const QString &tip, MoveButton button);
242 
243     /**
244      * Sets the whatsthis help for button @p button to @p text.
245      */
246     void setButtonWhatsThis(const QString &text, MoveButton button);
247 
248 Q_SIGNALS:
249     /**
250      * Emitted when an item is moved to the "selected" listbox.
251      */
252     void added(QListWidgetItem *item);
253 
254     /**
255      * Emitted when an item is moved out of the "selected" listbox.
256      */
257     void removed(QListWidgetItem *item);
258 
259     /**
260      * Emitted when an item is moved upwards in the "selected" listbox.
261      */
262     void movedUp(QListWidgetItem *item);
263 
264     /**
265      * Emitted when an item is moved downwards in the "selected" listbox.
266      */
267     void movedDown(QListWidgetItem *item);
268 
269     /**
270      * Emitted when an item is moved to the "selected" listbox.
271      */
272     //  void addedToSelection( QListWidgetItem *item );
273 
274 public Q_SLOTS:
275     /**
276      * Sets the enabled state of all moving buttons to reflect the current
277      * options.
278      *
279      * Be sure to call this if you add or removes items to either listbox after the
280      * widget is shown
281      */
282     void setButtonsEnabled();
283 
284 protected:
285     /**
286      * Reimplemented for internal reasons.
287      */
288     void keyPressEvent(QKeyEvent *) override;
289 
290     /**
291      * Reimplemented for internal reasons.
292      */
293     bool eventFilter(QObject *, QEvent *) override;
294 
295 private:
296     /**
297      * @private
298      * Private data storage
299      */
300     friend class KActionSelectorPrivate;
301     std::unique_ptr<class KActionSelectorPrivate> const d;
302 
303     Q_DISABLE_COPY(KActionSelector)
304 };
305 
306 #endif // _KACTION_SELECTOR_H_
307