1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qplatformtheme.h"
41
42#include "qplatformtheme_p.h"
43
44#include <QtCore/QVariant>
45#include <QtCore/QStringList>
46#include <QtCore/qfileinfo.h>
47#include <qicon.h>
48#include <qpalette.h>
49#include <qtextformat.h>
50#include <private/qiconloader_p.h>
51#include <private/qguiapplication_p.h>
52#include <qpa/qplatformintegration.h>
53#include <qpa/qplatformdialoghelper.h>
54
55#include <algorithm>
56
57QT_BEGIN_NAMESPACE
58
59/*!
60 \class QPlatformTheme
61 \since 5.0
62 \internal
63 \preliminary
64 \ingroup qpa
65 \brief The QPlatformTheme class allows customizing the UI based on themes.
66
67*/
68
69/*!
70 \enum QPlatformTheme::ThemeHint
71
72 This enum describes the available theme hints.
73
74 \value CursorFlashTime (int) Cursor flash time in ms, overriding
75 QPlatformIntegration::styleHint.
76
77 \value KeyboardInputInterval (int) Keyboard input interval in ms, overriding
78 QPlatformIntegration::styleHint.
79
80 \value MouseDoubleClickInterval (int) Mouse double click interval in ms,
81 overriding QPlatformIntegration::styleHint.
82
83 \value MouseDoubleClickDistance (int) The maximum distance in logical pixels which the mouse can travel
84 between clicks in order for the click sequence to be handled as a double click.
85 The default value is 5 logical pixels.
86
87 \value MousePressAndHoldInterval (int) Mouse press and hold interval in ms,
88 overriding QPlatformIntegration::styleHint.
89
90 \value StartDragDistance (int) Start drag distance,
91 overriding QPlatformIntegration::styleHint.
92
93 \value StartDragTime (int) Start drag time in ms,
94 overriding QPlatformIntegration::styleHint.
95
96 \value WheelScrollLines (int) The number of lines to scroll a widget, when the mouse wheel is rotated.
97 The default value is 3. \sa QApplication::wheelScrollLines()
98
99 \value KeyboardAutoRepeatRate (int) Keyboard auto repeat rate,
100 overriding QPlatformIntegration::styleHint.
101
102 \value PasswordMaskDelay (int) Pass word mask delay in ms,
103 overriding QPlatformIntegration::styleHint.
104
105 \value StartDragVelocity (int) Velocity of a drag,
106 overriding QPlatformIntegration::styleHint.
107
108 \value TextCursorWidth (int) Determines the width of the text cursor.
109
110 \value DropShadow (bool) Determines whether the drop shadow effect for
111 tooltips or whatsthis is enabled.
112
113 \value MaximumScrollBarDragDistance (int) Determines the value returned by
114 QStyle::pixelMetric(PM_MaximumDragDistance)
115
116 \value ToolButtonStyle (int) A value representing a Qt::ToolButtonStyle.
117
118 \value ToolBarIconSize Icon size for tool bars.
119
120 \value SystemIconThemeName (QString) Name of the icon theme.
121
122 \value SystemIconFallbackThemeName (QString) Name of the fallback icon theme.
123
124 \value IconThemeSearchPaths (QStringList) Search paths for icons.
125
126 \value ItemViewActivateItemOnSingleClick (bool) Activate items by single click.
127
128 \value StyleNames (QStringList) A list of preferred style names.
129
130 \value WindowAutoPlacement (bool) A boolean value indicating whether Windows
131 (particularly dialogs) are placed by the system
132 (see _NET_WM_FULL_PLACEMENT in X11).
133
134 \value DialogButtonBoxLayout (int) An integer representing a
135 QDialogButtonBox::ButtonLayout value.
136
137 \value DialogButtonBoxButtonsHaveIcons (bool) A boolean value indicating whether
138 the buttons of a QDialogButtonBox should have icons.
139
140 \value UseFullScreenForPopupMenu (bool) Pop menus can cover the full screen including task bar.
141
142 \value KeyboardScheme (int) An integer value (enum KeyboardSchemes) specifying the
143 keyboard scheme.
144
145 \value UiEffects (int) A flag value consisting of UiEffect values specifying the enabled UI animations.
146
147 \value SpellCheckUnderlineStyle (int) A QTextCharFormat::UnderlineStyle specifying
148 the underline style used misspelled words when spell checking.
149
150 \value TabFocusBehavior (int) A Qt::TabFocusBehavior specifying
151 the behavior of focus change when tab key was pressed.
152 This enum value was added in Qt 5.5.
153
154 \value DialogSnapToDefaultButton (bool) Whether the mouse should snap to the default button when a dialog
155 becomes visible.
156
157 \value ContextMenuOnMouseRelease (bool) Whether the context menu should be shown on mouse release.
158
159 \value TouchDoubleTapDistance (int) The maximum distance in logical pixels which a touchpoint can travel
160 between taps in order for the tap sequence to be handled as a double tap.
161 The default value is double the MouseDoubleClickDistance, or 10 logical pixels
162 if that is not specified.
163
164 \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
165
166 \sa themeHint(), QStyle::pixelMetric()
167*/
168
169
170#if QT_CONFIG(shortcut)
171// Table of key bindings. It must be sorted on key sequence:
172// The integer value of VK_KEY | Modifier Keys (e.g., VK_META, and etc.)
173// A priority of 1 indicates that this is the primary key binding when multiple are defined.
174
175enum KeyPlatform {
176 KB_Win = (1 << QPlatformTheme::WindowsKeyboardScheme),
177 KB_Mac = (1 << QPlatformTheme::MacKeyboardScheme),
178 KB_X11 = (1 << QPlatformTheme::X11KeyboardScheme),
179 KB_KDE = (1 << QPlatformTheme::KdeKeyboardScheme),
180 KB_Gnome = (1 << QPlatformTheme::GnomeKeyboardScheme),
181 KB_CDE = (1 << QPlatformTheme::CdeKeyboardScheme),
182 KB_All = 0xffff
183};
184
185const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
186 // StandardKey Priority Key Sequence Platforms
187 {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, KB_Mac},
188 {QKeySequence::HelpContents, 0, Qt::Key_F1, KB_Win | KB_X11},
189 {QKeySequence::WhatsThis, 1, Qt::SHIFT | Qt::Key_F1, KB_All},
190 {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, KB_All},
191 {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_F4, KB_Mac},
192 {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_F4, KB_Win},
193 {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, KB_Mac},
194 {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, KB_Win | KB_X11},
195 {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, KB_All},
196 {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, KB_All},
197 {QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, KB_X11}, //emacs (line edit only)
198 {QKeySequence::Delete, 1, Qt::Key_Delete, KB_All},
199 {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac},
200 {QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, KB_All},
201 {QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, KB_Win | KB_X11}, //## Check if this should work on mac
202 {QKeySequence::Cut, 0, Qt::Key_F20, KB_X11}, //Cut on sun keyboards
203 {QKeySequence::Cut, 0, Qt::META | Qt::Key_K, KB_Mac},
204 {QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, KB_X11 | KB_Win},
205 {QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, KB_All},
206 {QKeySequence::Copy, 0, Qt::Key_F16, KB_X11}, //Copy on sun keyboards
207 {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, KB_X11},
208 {QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, KB_All},
209 {QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, KB_Win | KB_X11},
210 {QKeySequence::Paste, 0, Qt::Key_F18, KB_X11}, //Paste on sun keyboards
211 {QKeySequence::Paste, 0, Qt::META | Qt::Key_Y, KB_Mac},
212 {QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, KB_Win},
213 {QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, KB_All},
214 {QKeySequence::Undo, 0, Qt::Key_F14, KB_X11}, //Undo on sun keyboards
215 {QKeySequence::Redo, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Backspace,KB_Win},
216 {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Mac},
217 {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Win | KB_X11},
218 {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, KB_Win},
219 {QKeySequence::Back, 1, Qt::ALT | Qt::Key_Left, KB_Win | KB_X11},
220 {QKeySequence::Back, 0, Qt::CTRL | Qt::Key_Left, KB_Mac},
221 {QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, KB_Mac},
222 {QKeySequence::Back, 0, Qt::Key_Backspace, KB_Win},
223 {QKeySequence::Forward, 1, Qt::ALT | Qt::Key_Right, KB_Win | KB_X11},
224 {QKeySequence::Forward, 0, Qt::CTRL | Qt::Key_Right, KB_Mac},
225 {QKeySequence::Forward, 1, Qt::CTRL | Qt::Key_BracketRight, KB_Mac},
226 {QKeySequence::Forward, 0, Qt::SHIFT | Qt::Key_Backspace, KB_Win},
227 {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, KB_Gnome | KB_Mac},
228 {QKeySequence::Refresh, 0, Qt::Key_F5, KB_Win | KB_X11},
229 {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, KB_All},
230 {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, KB_All},
231 {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, KB_All},
232 {QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, KB_KDE},
233 {QKeySequence::AddTab, 0, Qt::CTRL | Qt::Key_T, KB_All},
234 {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_F6, KB_Win},
235 {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Tab, KB_Mac}, //different priority from above
236 {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_Tab, KB_Win | KB_X11},
237 {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_BraceRight, KB_Mac},
238 {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, KB_KDE},
239 {QKeySequence::NextChild, 0, Qt::Key_Forward, KB_All},
240 {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F6, KB_Win},
241 {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Mac },//different priority from above
242 {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Win | KB_X11},
243 {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::Key_BraceLeft, KB_Mac},
244 {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, KB_KDE},
245 {QKeySequence::PreviousChild, 0, Qt::Key_Back, KB_All},
246 {QKeySequence::Find, 0, Qt::CTRL | Qt::Key_F, KB_All},
247 {QKeySequence::FindNext, 0, Qt::CTRL | Qt::Key_G, KB_Win},
248 {QKeySequence::FindNext, 1, Qt::CTRL | Qt::Key_G, KB_Gnome | KB_Mac},
249 {QKeySequence::FindNext, 1, Qt::Key_F3, KB_Win},
250 {QKeySequence::FindNext, 0, Qt::Key_F3, KB_X11},
251 {QKeySequence::FindPrevious, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Win},
252 {QKeySequence::FindPrevious, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Gnome | KB_Mac},
253 {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, KB_Win},
254 {QKeySequence::FindPrevious, 0, Qt::SHIFT | Qt::Key_F3, KB_X11},
255 {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, KB_KDE},
256 {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Gnome},
257 {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Win},
258 {QKeySequence::SelectAll, 1, Qt::CTRL | Qt::Key_A, KB_All},
259 {QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, KB_All},
260 {QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, KB_All},
261 {QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, KB_All},
262 {QKeySequence::MoveToNextChar, 1, Qt::Key_Right, KB_All},
263 {QKeySequence::MoveToNextChar, 0, Qt::META | Qt::Key_F, KB_Mac},
264 {QKeySequence::MoveToPreviousChar, 1, Qt::Key_Left, KB_All},
265 {QKeySequence::MoveToPreviousChar, 0, Qt::META | Qt::Key_B, KB_Mac},
266 {QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, KB_Mac},
267 {QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, KB_Win | KB_X11},
268 {QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, KB_Mac},
269 {QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, KB_Win | KB_X11},
270 {QKeySequence::MoveToNextLine, 1, Qt::Key_Down, KB_All},
271 {QKeySequence::MoveToNextLine, 0, Qt::META | Qt::Key_N, KB_Mac},
272 {QKeySequence::MoveToPreviousLine, 1, Qt::Key_Up, KB_All},
273 {QKeySequence::MoveToPreviousLine, 0, Qt::META | Qt::Key_P, KB_Mac},
274 {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, KB_Mac},
275 {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, KB_Mac},
276 {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_V, KB_Mac},
277 {QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, KB_Mac },
278 {QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, KB_All},
279 {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, KB_Mac},
280 {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_Up, KB_Mac},
281 {QKeySequence::MoveToPreviousPage, 0, Qt::ALT | Qt::Key_PageUp, KB_Mac },
282 {QKeySequence::MoveToPreviousPage, 1, Qt::Key_PageUp, KB_All},
283 {QKeySequence::MoveToStartOfLine, 0, Qt::META | Qt::Key_Left, KB_Mac},
284 {QKeySequence::MoveToStartOfLine, 0, Qt::CTRL | Qt::Key_Left, KB_Mac },
285 {QKeySequence::MoveToStartOfLine, 0, Qt::Key_Home, KB_Win | KB_X11},
286 {QKeySequence::MoveToEndOfLine, 0, Qt::META | Qt::Key_Right, KB_Mac},
287 {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL | Qt::Key_Right, KB_Mac },
288 {QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, KB_Win | KB_X11},
289 {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL | Qt::Key_E, KB_X11},
290 {QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, KB_Mac},
291 {QKeySequence::MoveToStartOfBlock, 1, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only
292 {QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, KB_Mac},
293 {QKeySequence::MoveToEndOfBlock, 1, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only
294 {QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, KB_Mac},
295 {QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, KB_Win | KB_X11},
296 {QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, KB_Mac},
297 {QKeySequence::MoveToEndOfDocument, 1, Qt::CTRL | Qt::Key_Down, KB_Mac},
298 {QKeySequence::MoveToEndOfDocument, 0, Qt::CTRL | Qt::Key_End, KB_Win | KB_X11},
299 {QKeySequence::MoveToEndOfDocument, 0, Qt::Key_End, KB_Mac},
300 {QKeySequence::SelectNextChar, 0, Qt::SHIFT | Qt::Key_Right, KB_All},
301 {QKeySequence::SelectPreviousChar, 0, Qt::SHIFT | Qt::Key_Left, KB_All},
302 {QKeySequence::SelectNextWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Right, KB_Mac},
303 {QKeySequence::SelectNextWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Win | KB_X11},
304 {QKeySequence::SelectPreviousWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Left, KB_Mac},
305 {QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Win | KB_X11},
306 {QKeySequence::SelectNextLine, 0, Qt::SHIFT | Qt::Key_Down, KB_All},
307 {QKeySequence::SelectPreviousLine, 0, Qt::SHIFT | Qt::Key_Up, KB_All},
308 {QKeySequence::SelectNextPage, 0, Qt::SHIFT | Qt::Key_PageDown, KB_All},
309 {QKeySequence::SelectPreviousPage, 0, Qt::SHIFT | Qt::Key_PageUp, KB_All},
310 {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, KB_Mac},
311 {QKeySequence::SelectStartOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Mac },
312 {QKeySequence::SelectStartOfLine, 0, Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
313 {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, KB_Mac},
314 {QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Mac },
315 {QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
316 {QKeySequence::SelectStartOfBlock, 1, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only
317 {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, KB_Mac},
318 {QKeySequence::SelectEndOfBlock, 1, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only
319 {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, KB_Mac},
320 {QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, KB_Mac},
321 {QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
322 {QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, KB_Mac},
323 {QKeySequence::SelectEndOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Down, KB_Mac},
324 {QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
325 {QKeySequence::SelectEndOfDocument, 0, Qt::SHIFT | Qt::Key_End, KB_Mac},
326 {QKeySequence::DeleteStartOfWord, 0, Qt::ALT | Qt::Key_Backspace, KB_Mac},
327 {QKeySequence::DeleteStartOfWord, 0, Qt::CTRL | Qt::Key_Backspace, KB_X11 | KB_Win},
328 {QKeySequence::DeleteEndOfWord, 0, Qt::ALT | Qt::Key_Delete, KB_Mac},
329 {QKeySequence::DeleteEndOfWord, 0, Qt::CTRL | Qt::Key_Delete, KB_X11 | KB_Win},
330 {QKeySequence::DeleteEndOfLine, 0, Qt::CTRL | Qt::Key_K, KB_X11}, //emacs (line edit only)
331 {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Enter, KB_All},
332 {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Return, KB_All},
333 {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Enter, KB_Mac},
334 {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, KB_Mac},
335 {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, KB_All},
336 {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, KB_All},
337 {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_O, KB_Mac},
338 {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac},
339 {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac},
340 {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_X11 | KB_Gnome | KB_KDE | KB_Mac},
341 {QKeySequence::FullScreen, 1, Qt::META | Qt::CTRL | Qt::Key_F, KB_Mac},
342 {QKeySequence::FullScreen, 0, Qt::ALT | Qt::Key_Enter, KB_Win},
343 {QKeySequence::FullScreen, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F, KB_KDE},
344 {QKeySequence::FullScreen, 1, Qt::CTRL | Qt::Key_F11, KB_Gnome},
345 {QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
346 {QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11},
347 {QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, KB_X11},
348 {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac},
349 {QKeySequence::Cancel, 0, Qt::Key_Escape, KB_All},
350 {QKeySequence::Cancel, 0, Qt::CTRL | Qt::Key_Period, KB_Mac}
351};
352
353const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding));
354#endif
355
356QPlatformThemePrivate::QPlatformThemePrivate()
357 : systemPalette(nullptr)
358{ }
359
360QPlatformThemePrivate::~QPlatformThemePrivate()
361{
362 delete systemPalette;
363}
364
365Q_GUI_EXPORT QPalette qt_fusionPalette();
366
367void QPlatformThemePrivate::initializeSystemPalette()
368{
369 Q_ASSERT(!systemPalette);
370 systemPalette = new QPalette(qt_fusionPalette());
371}
372
373QPlatformTheme::QPlatformTheme()
374 : d_ptr(new QPlatformThemePrivate)
375{
376
377}
378
379QPlatformTheme::QPlatformTheme(QPlatformThemePrivate *priv)
380 : d_ptr(priv)
381{ }
382
383QPlatformTheme::~QPlatformTheme()
384{
385
386}
387
388bool QPlatformTheme::usePlatformNativeDialog(DialogType type) const
389{
390 Q_UNUSED(type);
391 return false;
392}
393
394QPlatformDialogHelper *QPlatformTheme::createPlatformDialogHelper(DialogType type) const
395{
396 Q_UNUSED(type);
397 return nullptr;
398}
399
400const QPalette *QPlatformTheme::palette(Palette type) const
401{
402 Q_D(const QPlatformTheme);
403 if (type == QPlatformTheme::SystemPalette) {
404 if (!d->systemPalette)
405 const_cast<QPlatformTheme *>(this)->d_ptr->initializeSystemPalette();
406 return d->systemPalette;
407 }
408 return nullptr;
409}
410
411const QFont *QPlatformTheme::font(Font type) const
412{
413 Q_UNUSED(type);
414 return nullptr;
415}
416
417QPixmap QPlatformTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
418{
419 Q_UNUSED(sp);
420 Q_UNUSED(size);
421 // TODO Should return QCommonStyle pixmaps?
422 return QPixmap();
423}
424
425/*!
426 \brief Return an icon for \a fileInfo, observing \a iconOptions.
427
428 This function is queried by QFileIconProvider and similar classes to obtain
429 an icon for a file. If it does not return a non-null icon, fileIconPixmap()
430 is queried for a specific size.
431
432 \since 5.8
433*/
434
435QIcon QPlatformTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const
436{
437 Q_UNUSED(fileInfo);
438 Q_UNUSED(iconOptions);
439 // TODO Should return QCommonStyle pixmaps?
440 return QIcon();
441}
442
443QVariant QPlatformTheme::themeHint(ThemeHint hint) const
444{
445 // For theme hints which mirror platform integration style hints, query
446 // the platform integration. The base QPlatformIntegration::styleHint()
447 // function will in turn query QPlatformTheme::defaultThemeHint() if there
448 // is no custom value.
449 switch (hint) {
450 case QPlatformTheme::CursorFlashTime:
451 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::CursorFlashTime);
452 case QPlatformTheme::KeyboardInputInterval:
453 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::KeyboardInputInterval);
454 case QPlatformTheme::KeyboardAutoRepeatRate:
455 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::KeyboardAutoRepeatRate);
456 case QPlatformTheme::MouseDoubleClickInterval:
457 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::MouseDoubleClickInterval);
458 case QPlatformTheme::StartDragDistance:
459 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::StartDragDistance);
460 case QPlatformTheme::StartDragTime:
461 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::StartDragTime);
462 case QPlatformTheme::StartDragVelocity:
463 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::StartDragVelocity);
464 case QPlatformTheme::PasswordMaskDelay:
465 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::PasswordMaskDelay);
466 case QPlatformTheme::PasswordMaskCharacter:
467 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::PasswordMaskCharacter);
468 case QPlatformTheme::MousePressAndHoldInterval:
469 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::MousePressAndHoldInterval);
470 case QPlatformTheme::ItemViewActivateItemOnSingleClick:
471 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ItemViewActivateItemOnSingleClick);
472 case QPlatformTheme::UiEffects:
473 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::UiEffects);
474 case QPlatformTheme::ShowShortcutsInContextMenus:
475 return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ShowShortcutsInContextMenus);
476 default:
477 return QPlatformTheme::defaultThemeHint(hint);
478 }
479}
480
481QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
482{
483 switch (hint) {
484 case QPlatformTheme::CursorFlashTime:
485 return QVariant(1000);
486 case QPlatformTheme::KeyboardInputInterval:
487 return QVariant(400);
488 case QPlatformTheme::KeyboardAutoRepeatRate:
489 return QVariant(30);
490 case QPlatformTheme::MouseDoubleClickInterval:
491 return QVariant(400);
492 case QPlatformTheme::StartDragDistance:
493 return QVariant(10);
494 case QPlatformTheme::StartDragTime:
495 return QVariant(500);
496 case QPlatformTheme::PasswordMaskDelay:
497 return QVariant(int(0));
498 case QPlatformTheme::PasswordMaskCharacter:
499 return QVariant(QChar(u'\x25CF'));
500 case QPlatformTheme::StartDragVelocity:
501 return QVariant(int(0)); // no limit
502 case QPlatformTheme::UseFullScreenForPopupMenu:
503 return QVariant(false);
504 case QPlatformTheme::WindowAutoPlacement:
505 return QVariant(false);
506 case QPlatformTheme::DialogButtonBoxLayout:
507 return QVariant(int(0));
508 case QPlatformTheme::DialogButtonBoxButtonsHaveIcons:
509 return QVariant(false);
510 case QPlatformTheme::ItemViewActivateItemOnSingleClick:
511 return QVariant(false);
512 case QPlatformTheme::ToolButtonStyle:
513 return QVariant(int(Qt::ToolButtonIconOnly));
514 case QPlatformTheme::ToolBarIconSize:
515 return QVariant(int(0));
516 case QPlatformTheme::SystemIconThemeName:
517 case QPlatformTheme::SystemIconFallbackThemeName:
518 return QVariant(QString());
519 case QPlatformTheme::IconThemeSearchPaths:
520 return QVariant(QStringList());
521 case QPlatformTheme::IconFallbackSearchPaths:
522 return QVariant(QStringList());
523 case QPlatformTheme::StyleNames:
524 return QVariant(QStringList());
525 case QPlatformTheme::ShowShortcutsInContextMenus:
526 return QVariant(true);
527 case TextCursorWidth:
528 return QVariant(1);
529 case DropShadow:
530 return QVariant(false);
531 case MaximumScrollBarDragDistance:
532 return QVariant(-1);
533 case KeyboardScheme:
534 return QVariant(int(WindowsKeyboardScheme));
535 case UiEffects:
536 return QVariant(int(0));
537 case SpellCheckUnderlineStyle:
538 return QVariant(int(QTextCharFormat::WaveUnderline));
539 case TabFocusBehavior:
540 return QVariant(int(Qt::TabFocusAllControls));
541 case IconPixmapSizes:
542 return QVariant::fromValue(QList<int>());
543 case DialogSnapToDefaultButton:
544 case ContextMenuOnMouseRelease:
545 return QVariant(false);
546 case MousePressAndHoldInterval:
547 return QVariant(800);
548 case MouseDoubleClickDistance:
549 {
550 bool ok = false;
551 const int dist = qEnvironmentVariableIntValue("QT_DBL_CLICK_DIST", &ok);
552 return QVariant(ok ? dist : 5);
553 }
554 case WheelScrollLines:
555 return QVariant(3);
556 case TouchDoubleTapDistance:
557 {
558 bool ok = false;
559 int dist = qEnvironmentVariableIntValue("QT_DBL_TAP_DIST", &ok);
560 if (!ok)
561 dist = defaultThemeHint(MouseDoubleClickDistance).toInt(&ok) * 2;
562 return QVariant(ok ? dist : 10);
563 }
564 case MouseQuickSelectionThreshold:
565 return QVariant(10);
566 }
567 return QVariant();
568}
569
570QPlatformMenuItem *QPlatformTheme::createPlatformMenuItem() const
571{
572 return nullptr;
573}
574
575QPlatformMenu *QPlatformTheme::createPlatformMenu() const
576{
577 return nullptr;
578}
579
580QPlatformMenuBar *QPlatformTheme::createPlatformMenuBar() const
581{
582 return nullptr;
583}
584
585#ifndef QT_NO_SYSTEMTRAYICON
586/*!
587 Factory function for QSystemTrayIcon. This function will return 0 if the platform
588 integration does not support creating any system tray icon.
589*/
590QPlatformSystemTrayIcon *QPlatformTheme::createPlatformSystemTrayIcon() const
591{
592 return nullptr;
593}
594#endif
595
596/*!
597 Factory function for the QIconEngine used by QIcon::fromTheme(). By default this
598 function returns a QIconLoaderEngine, but subclasses can reimplement it to
599 provide their own.
600
601 It is especially useful to benefit from some platform specific facilities or
602 optimizations like an inter-process cache in systems mostly built with Qt.
603
604 \since 5.1
605*/
606QIconEngine *QPlatformTheme::createIconEngine(const QString &iconName) const
607{
608 return new QIconLoaderEngine(iconName);
609}
610
611#if QT_CONFIG(shortcut)
612// mixed-mode predicate: all of these overloads are actually needed (but not all for every compiler)
613struct ByStandardKey {
614 typedef bool result_type;
615
616 bool operator()(QKeySequence::StandardKey lhs, QKeySequence::StandardKey rhs) const
617 { return lhs < rhs; }
618
619 bool operator()(const QKeyBinding& lhs, const QKeyBinding& rhs) const
620 { return operator()(lhs.standardKey, rhs.standardKey); }
621
622 bool operator()(QKeySequence::StandardKey lhs, const QKeyBinding& rhs) const
623 { return operator()(lhs, rhs.standardKey); }
624
625 bool operator()(const QKeyBinding& lhs, QKeySequence::StandardKey rhs) const
626 { return operator()(lhs.standardKey, rhs); }
627};
628
629/*!
630 Returns the key sequence that should be used for a standard action.
631
632 \since 5.2
633 */
634QList<QKeySequence> QPlatformTheme::keyBindings(QKeySequence::StandardKey key) const
635{
636 const uint platform = QPlatformThemePrivate::currentKeyPlatforms();
637 QList <QKeySequence> list;
638
639 std::pair<const QKeyBinding *, const QKeyBinding *> range =
640 std::equal_range(QPlatformThemePrivate::keyBindings,
641 QPlatformThemePrivate::keyBindings + QPlatformThemePrivate::numberOfKeyBindings,
642 key, ByStandardKey());
643
644 for (const QKeyBinding *it = range.first; it < range.second; ++it) {
645 if (!(it->platform & platform))
646 continue;
647
648 uint shortcut = it->shortcut.toCombined();
649
650 if (it->priority > 0)
651 list.prepend(QKeySequence(shortcut));
652 else
653 list.append(QKeySequence(shortcut));
654 }
655
656 return list;
657}
658#endif
659
660/*!
661 Returns the text of a standard \a button.
662
663 \since 5.3
664 \sa QPlatformDialogHelper::StandardButton
665 */
666
667QString QPlatformTheme::standardButtonText(int button) const
668{
669 return QPlatformTheme::defaultStandardButtonText(button);
670}
671
672#if QT_CONFIG(shortcut)
673/*!
674 Returns the mnemonic that should be used for a standard \a button.
675
676 \since 5.9
677 \sa QPlatformDialogHelper::StandardButton
678 */
679
680QKeySequence QPlatformTheme::standardButtonShortcut(int button) const
681{
682 Q_UNUSED(button);
683 return QKeySequence();
684}
685#endif // QT_CONFIG(shortcut)
686
687QString QPlatformTheme::defaultStandardButtonText(int button)
688{
689 switch (button) {
690 case QPlatformDialogHelper::Ok:
691 return QCoreApplication::translate("QPlatformTheme", "OK");
692 case QPlatformDialogHelper::Save:
693 return QCoreApplication::translate("QPlatformTheme", "Save");
694 case QPlatformDialogHelper::SaveAll:
695 return QCoreApplication::translate("QPlatformTheme", "Save All");
696 case QPlatformDialogHelper::Open:
697 return QCoreApplication::translate("QPlatformTheme", "Open");
698 case QPlatformDialogHelper::Yes:
699 return QCoreApplication::translate("QPlatformTheme", "&Yes");
700 case QPlatformDialogHelper::YesToAll:
701 return QCoreApplication::translate("QPlatformTheme", "Yes to &All");
702 case QPlatformDialogHelper::No:
703 return QCoreApplication::translate("QPlatformTheme", "&No");
704 case QPlatformDialogHelper::NoToAll:
705 return QCoreApplication::translate("QPlatformTheme", "N&o to All");
706 case QPlatformDialogHelper::Abort:
707 return QCoreApplication::translate("QPlatformTheme", "Abort");
708 case QPlatformDialogHelper::Retry:
709 return QCoreApplication::translate("QPlatformTheme", "Retry");
710 case QPlatformDialogHelper::Ignore:
711 return QCoreApplication::translate("QPlatformTheme", "Ignore");
712 case QPlatformDialogHelper::Close:
713 return QCoreApplication::translate("QPlatformTheme", "Close");
714 case QPlatformDialogHelper::Cancel:
715 return QCoreApplication::translate("QPlatformTheme", "Cancel");
716 case QPlatformDialogHelper::Discard:
717 return QCoreApplication::translate("QPlatformTheme", "Discard");
718 case QPlatformDialogHelper::Help:
719 return QCoreApplication::translate("QPlatformTheme", "Help");
720 case QPlatformDialogHelper::Apply:
721 return QCoreApplication::translate("QPlatformTheme", "Apply");
722 case QPlatformDialogHelper::Reset:
723 return QCoreApplication::translate("QPlatformTheme", "Reset");
724 case QPlatformDialogHelper::RestoreDefaults:
725 return QCoreApplication::translate("QPlatformTheme", "Restore Defaults");
726 default:
727 break;
728 }
729 return QString();
730}
731
732QString QPlatformTheme::removeMnemonics(const QString &original)
733{
734 QString returnText(original.size(), u'\0');
735 int finalDest = 0;
736 int currPos = 0;
737 int l = original.length();
738 while (l) {
739 if (original.at(currPos) == QLatin1Char('&')) {
740 ++currPos;
741 --l;
742 if (l == 0)
743 break;
744 } else if (original.at(currPos) == QLatin1Char('(') && l >= 4 &&
745 original.at(currPos + 1) == QLatin1Char('&') &&
746 original.at(currPos + 2) != QLatin1Char('&') &&
747 original.at(currPos + 3) == QLatin1Char(')')) {
748 /* remove mnemonics its format is "\s*(&X)" */
749 int n = 0;
750 while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
751 ++n;
752 finalDest -= n;
753 currPos += 4;
754 l -= 4;
755 continue;
756 }
757 returnText[finalDest] = original.at(currPos);
758 ++currPos;
759 ++finalDest;
760 --l;
761 }
762 returnText.truncate(finalDest);
763 return returnText;
764}
765
766unsigned QPlatformThemePrivate::currentKeyPlatforms()
767{
768 const uint keyboardScheme = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt();
769 unsigned result = 1u << keyboardScheme;
770#if QT_CONFIG(shortcut)
771 if (keyboardScheme == QPlatformTheme::KdeKeyboardScheme
772 || keyboardScheme == QPlatformTheme::GnomeKeyboardScheme
773 || keyboardScheme == QPlatformTheme::CdeKeyboardScheme)
774 result |= KB_X11;
775#endif
776 return result;
777}
778
779QT_END_NAMESPACE
780