1/********************************************************************
2KWin - the KDE window manager
3This file is part of the KDE project.
4
5Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19*********************************************************************/
20#ifndef KWIN_USERACTIONS_H
21#define KWIN_USERACTIONS_H
22
23// KDE
24#include <KDE/KDialog>
25// Qt
26#include <QObject>
27#include <QWeakPointer>
28
29class KKeySequenceWidget;
30class QAction;
31class QLabel;
32class QMenu;
33class QRect;
34
35namespace KWin
36{
37class Client;
38
39/**
40 * @brief Menu shown for a Client.
41 *
42 * The UserActionsMenu implements the Menu which is shown on:
43 * @li context-menu event on Window decoration
44 * @li window menu button
45 * @li Keyboard Shortcut (by default Alt+F3)
46 *
47 * The menu contains various window management related actions for the Client the menu is opened
48 * for, this is normally the active Client.
49 *
50 * The menu which is shown is tried to be as close as possible to the menu implemented in
51 * libtaskmanager, though there are differences as there are some actions only the window manager
52 * can provide and on the other hand the libtaskmanager cares also about things like e.g. grouping.
53 *
54 * Whenever the menu is changed it should be tried to also adjust the menu in libtaskmanager.
55 *
56 * @author Martin Gräßlin <mgraesslin@kde.org>
57 **/
58class UserActionsMenu : public QObject
59{
60 Q_OBJECT
61public:
62 explicit UserActionsMenu(QObject *parent = 0);
63 virtual ~UserActionsMenu();
64 /**
65 * Discards the constructed menu, so that it gets recreates
66 * on next show event.
67 * @see show
68 **/
69 void discard();
70
71 /**
72 * @returns Whether the menu is currently visible
73 **/
74 bool isShown() const;
75 /**
76 * @returns Whether the menu has a Client set to operate on.
77 **/
78 bool hasClient() const;
79 /**
80 * Checks whether the given Client @p c is the Client
81 * for which the Menu is shown.
82 * @param c The Client to compare
83 * @returns Whether the Client is the one related to this Menu
84 **/
85 bool isMenuClient(const Client *c) const;
86 /**
87 * Closes the Menu and prepares it for next usage.
88 **/
89 void close();
90 /**
91 * @brief Shows the menu at the given @p pos for the given @p client.
92 *
93 * @param pos The position where the menu should be shown.
94 * @param client The Client for which the Menu has to be shown.
95 **/
96 void show(const QRect &pos, const QWeakPointer<Client> &client);
97
98public slots:
99 /**
100 * Delayed initialization of the activity menu.
101 *
102 * The call to retrieve the current list of activities is performed in a thread and this
103 * slot is invoked once the list has been fetched. Only task of this method is to decide
104 * whether to show the activity menu and to invoke the initialization of it.
105 *
106 * @see initActivityPopup
107 **/
108 void showHideActivityMenu();
109
110private slots:
111 /**
112 * The menu will become visible soon.
113 *
114 * Adjust the items according to the respective Client.
115 **/
116 void menuAboutToShow();
117 /**
118 * Adjusts the add to tab group menu to the current value of the Client.
119 **/
120 void rebuildTabGroupPopup();
121 /**
122 * Adjusts the switch to tab menu to the current values of the Client.
123 **/
124 void rebuildTabListPopup();
125 /**
126 * Adds the Client as tab to the Client identified by the @p action.
127 *
128 * @param action The invoked action containing the Client to which the active Client should be tabbed.
129 **/
130 void entabPopupClient(QAction *action);
131 /**
132 * Activates the selected tabbed Client.
133 *
134 * @param action The invoked action containing the tabbed Client which should be activated.
135 **/
136 void selectPopupClientTab(QAction *action);
137 /**
138 * Adjusts the desktop popup to the current values and the location of
139 * the Client.
140 **/
141 void desktopPopupAboutToShow();
142 /**
143 * Adjusts the screen popup to the current values and the location of
144 * the Client.
145 **/
146 void screenPopupAboutToShow();
147 /**
148 * Adjusts the activity popup to the current values and the location of
149 * the Client.
150 **/
151 void activityPopupAboutToShow();
152 /**
153 * Sends the client to desktop \a desk
154 *
155 * @param action Invoked Action containing the Desktop as data element
156 **/
157 void slotSendToDesktop(QAction *action);
158 /**
159 * Sends the Client to screen \a screen
160 *
161 * @param action Invoked Action containing the Screen as data element
162 **/
163 void slotSendToScreen(QAction *action);
164 /**
165 * Toggles whether the Client is on the \a activity
166 *
167 * @param action Invoked Action containing the Id of the Activity to toggle the Client on
168 **/
169 void slotToggleOnActivity(QAction *action);
170 /**
171 * Performs a window operation.
172 *
173 * @param action Invoked Action containing the Window Operation to perform for the Client
174 **/
175 void slotWindowOperation(QAction *action);
176 /**
177 * Invokes the kcmshell with the Window Manager related config modules.
178 **/
179 void configureWM();
180
181private:
182 /**
183 * Creates the menu if not already created.
184 **/
185 void init();
186 /**
187 * Creates the Move To Desktop sub-menu.
188 **/
189 void initDesktopPopup();
190 /**
191 * Creates the Move To Screen sub-menu.
192 **/
193 void initScreenPopup();
194 /**
195 * Creates activity popup.
196 * I'm going with checkable ones instead of "copy to" and "move to" menus; I *think* it's an easier way.
197 * Oh, and an 'all' option too of course
198 **/
199 void initActivityPopup();
200 /**
201 * Creates the Window Tabbing related menus.
202 **/
203 void initTabbingPopups();
204 /**
205 * Shows a helper Dialog to inform the user how to get back in case he triggered
206 * an action which hides the window decoration (e.g. NoBorder or Fullscreen).
207 * @param message The message type to be shown
208 * @param c The Client for which the dialog should be shown.
209 **/
210 void helperDialog(const QString &message, const QWeakPointer<Client> &c);
211 /**
212 * The actual main context menu which is show when the UserActionsMenu is invoked.
213 **/
214 QMenu* m_menu;
215 /**
216 * The move to desktop sub menu.
217 **/
218 QMenu* m_desktopMenu;
219 /**
220 * The move to screen sub menu.
221 **/
222 QMenu* m_screenMenu;
223 /**
224 * The activities sub menu.
225 **/
226 QMenu* m_activityMenu;
227 /**
228 * Menu to add the group to other group.
229 **/
230 QMenu* m_addTabsMenu;
231 /**
232 * Menu to change tab.
233 **/
234 QMenu* m_switchToTabMenu;
235 /**
236 * Menu for further entries added by scripts.
237 **/
238 QMenu* m_scriptsMenu;
239 QAction* m_resizeOperation;
240 QAction* m_moveOperation;
241 QAction* m_maximizeOperation;
242 QAction* m_shadeOperation;
243 QAction* m_keepAboveOperation;
244 QAction* m_keepBelowOperation;
245 QAction* m_fullScreenOperation;
246 QAction* m_noBorderOperation;
247 QAction* m_minimizeOperation;
248 QAction* m_closeOperation;
249 /**
250 * Remove client from group.
251 **/
252 QAction* m_removeFromTabGroup;
253 /**
254 * Close all clients in the group.
255 **/
256 QAction* m_closeTabGroup;
257 /**
258 * The Client for which the menu is shown.
259 **/
260 QWeakPointer<Client> m_client;
261};
262
263class ShortcutDialog
264 : public KDialog
265{
266 Q_OBJECT
267public:
268 explicit ShortcutDialog(const QKeySequence& cut);
269 virtual void accept();
270 QKeySequence shortcut() const;
271public Q_SLOTS:
272 void keySequenceChanged(const QKeySequence &seq);
273signals:
274 void dialogDone(bool ok);
275protected:
276 virtual void done(int r);
277private:
278 KKeySequenceWidget* widget;
279 QKeySequence _shortcut;
280 QLabel *warning;
281};
282
283} // namespace
284
285#endif // KWIN_USERACTIONS_H
286