qt4-b-gone: Remove all code supporting Qt < 5.5 and KDE4
[quassel.git] / src / uisupport / graphicalui.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This contains code from KStatusNotifierItem, part of the KDE libs     *
6  *   Copyright (C) 2009 Marco Martin <notmart@gmail.com>                   *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) version 3.                                           *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
22  ***************************************************************************/
23
24 #include "graphicalui.h"
25
26 #include "actioncollection.h"
27 #include "uisettings.h"
28 #include "contextmenuactionprovider.h"
29 #include "toolbaractionprovider.h"
30
31 #ifdef Q_WS_X11
32 #  include <QX11Info>
33 #endif
34
35 QWidget *GraphicalUi::_mainWidget = 0;
36 QHash<QString, ActionCollection *> GraphicalUi::_actionCollections;
37 ContextMenuActionProvider *GraphicalUi::_contextMenuActionProvider = 0;
38 ToolBarActionProvider *GraphicalUi::_toolBarActionProvider = 0;
39 UiStyle *GraphicalUi::_uiStyle = 0;
40
41
42 GraphicalUi::GraphicalUi(QObject *parent) : AbstractUi(parent), Singleton<GraphicalUi>(this)
43 {
44 #ifdef Q_OS_WIN
45     _dwTickCount = 0;
46 #endif
47 #ifdef Q_OS_MAC
48     GetFrontProcess(&_procNum);
49 #endif
50 }
51
52
53 void GraphicalUi::init()
54 {
55 #ifdef Q_OS_WIN
56     mainWidget()->installEventFilter(this);
57 #endif
58 }
59
60
61 ActionCollection *GraphicalUi::actionCollection(const QString &category, const QString &translatedCategory)
62 {
63     if (_actionCollections.contains(category))
64         return _actionCollections.value(category);
65     ActionCollection *coll = new ActionCollection(_mainWidget);
66
67     if (!translatedCategory.isEmpty())
68         coll->setProperty("Category", translatedCategory);
69     else
70         coll->setProperty("Category", category);
71
72     if (_mainWidget)
73         coll->addAssociatedWidget(_mainWidget);
74     _actionCollections.insert(category, coll);
75     return coll;
76 }
77
78
79 QHash<QString, ActionCollection *> GraphicalUi::actionCollections()
80 {
81     return _actionCollections;
82 }
83
84
85 void GraphicalUi::loadShortcuts()
86 {
87     foreach(ActionCollection *coll, actionCollections())
88     coll->readSettings();
89 }
90
91
92 void GraphicalUi::saveShortcuts()
93 {
94     ShortcutSettings s;
95     s.clear();
96     foreach(ActionCollection *coll, actionCollections())
97     coll->writeSettings();
98 }
99
100
101 void GraphicalUi::setMainWidget(QWidget *widget)
102 {
103     _mainWidget = widget;
104 }
105
106
107 void GraphicalUi::setContextMenuActionProvider(ContextMenuActionProvider *provider)
108 {
109     _contextMenuActionProvider = provider;
110 }
111
112
113 void GraphicalUi::setToolBarActionProvider(ToolBarActionProvider *provider)
114 {
115     _toolBarActionProvider = provider;
116 }
117
118
119 void GraphicalUi::setUiStyle(UiStyle *style)
120 {
121     _uiStyle = style;
122 }
123
124
125 void GraphicalUi::disconnectedFromCore()
126 {
127     _contextMenuActionProvider->disconnectedFromCore();
128     _toolBarActionProvider->disconnectedFromCore();
129     AbstractUi::disconnectedFromCore();
130 }
131
132
133 bool GraphicalUi::eventFilter(QObject *obj, QEvent *event)
134 {
135 #ifdef Q_OS_WIN
136     if (obj == mainWidget() && event->type() == QEvent::ActivationChange) {
137         _dwTickCount = GetTickCount();
138     }
139 #endif
140     return AbstractUi::eventFilter(obj, event);
141 }
142
143
144 // NOTE: Window activation stuff seems to work just fine in Plasma 5 without requiring X11 hacks.
145 // TODO: Evaluate cleaning all this up once we can get rid of Qt4/KDE4
146
147 // Code taken from KStatusNotifierItem for handling minimize/restore
148
149 bool GraphicalUi::checkMainWidgetVisibility(bool perform)
150 {
151 #ifdef Q_OS_WIN
152     // the problem is that we lose focus when the systray icon is activated
153     // and we don't know the former active window
154     // therefore we watch for activation event and use our stopwatch :)
155     if (GetTickCount() - _dwTickCount < 300) {
156         // we were active in the last 300ms -> hide it
157         if (perform)
158             minimizeRestore(false);
159         return false;
160     }
161     else {
162         if (perform)
163             minimizeRestore(true);
164         return true;
165     }
166
167 #else
168
169     if (!mainWidget()->isVisible() || mainWidget()->isMinimized() || !mainWidget()->isActiveWindow()) {
170         if (perform)
171             minimizeRestore(true);
172         return true;
173     }
174     else {
175         if (perform)
176             minimizeRestore(false);
177         return false;
178     }
179
180 #endif
181
182     return true;
183 }
184
185
186 bool GraphicalUi::isMainWidgetVisible()
187 {
188     return !instance()->checkMainWidgetVisibility(false);
189 }
190
191
192 void GraphicalUi::minimizeRestore(bool show)
193 {
194     if (show)
195         activateMainWidget();
196     else
197         hideMainWidget();
198 }
199
200
201 void GraphicalUi::activateMainWidget()
202 {
203 #ifdef Q_WS_X11
204     // Bypass focus stealing prevention
205     QX11Info::setAppUserTime(QX11Info::appTime());
206 #endif
207
208     if (mainWidget()->windowState() & Qt::WindowMinimized) {
209         // restore
210         mainWidget()->setWindowState((mainWidget()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
211     }
212
213     // this does not actually work on all platforms... and causes more evil than good
214     // mainWidget()->move(mainWidget()->frameGeometry().topLeft()); // avoid placement policies
215 #ifdef Q_OS_MAC
216     SetFrontProcess(&instance()->_procNum);
217 #else
218     mainWidget()->show();
219     mainWidget()->raise();
220     mainWidget()->activateWindow();
221 #endif
222 }
223
224
225 void GraphicalUi::hideMainWidget()
226 {
227     if (instance()->isHidingMainWidgetAllowed())
228 #ifdef Q_OS_MAC
229         ShowHideProcess(&instance()->_procNum, false);
230 #else
231         mainWidget()->hide();
232 #endif
233 }
234
235
236 void GraphicalUi::toggleMainWidget()
237 {
238     instance()->checkMainWidgetVisibility(true);
239 }