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#ifndef QT_NO_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(0)
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 0;
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 0;
409}
410
411const QFont *QPlatformTheme::font(Font type) const
412{
413 Q_UNUSED(type)
414 return 0;
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(0x25CF));
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 0;
573}
574
575QPlatformMenu *QPlatformTheme::createPlatformMenu() const
576{
577 return 0;
578}
579
580QPlatformMenuBar *QPlatformTheme::createPlatformMenuBar() const
581{
582 return 0;
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 0;
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 defined(Q_OS_MACX)
612static inline int maybeSwapShortcut(int shortcut)
613{
614 if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
615 uint oldshortcut = shortcut;
616 shortcut &= ~(Qt::CTRL | Qt::META);
617 if (oldshortcut & Qt::CTRL)
618 shortcut |= Qt::META;
619 if (oldshortcut & Qt::META)
620 shortcut |= Qt::CTRL;
621 }
622 return shortcut;
623}
624#endif
625
626#ifndef QT_NO_SHORTCUT
627// mixed-mode predicate: all of these overloads are actually needed (but not all for every compiler)
628struct ByStandardKey {
629 typedef bool result_type;
630
631 bool operator()(QKeySequence::StandardKey lhs, QKeySequence::StandardKey rhs) const
632 { return lhs < rhs; }
633
634 bool operator()(const QKeyBinding& lhs, const QKeyBinding& rhs) const
635 { return operator()(lhs.standardKey, rhs.standardKey); }
636
637 bool operator()(QKeySequence::StandardKey lhs, const QKeyBinding& rhs) const
638 { return operator()(lhs, rhs.standardKey); }
639
640 bool operator()(const QKeyBinding& lhs, QKeySequence::StandardKey rhs) const
641 { return operator()(lhs.standardKey, rhs); }
642};
643
644/*!
645 Returns the key sequence that should be used for a standard action.
646
647 \since 5.2
648 */
649QList<QKeySequence> QPlatformTheme::keyBindings(QKeySequence::StandardKey key) const
650{
651 const uint platform = QPlatformThemePrivate::currentKeyPlatforms();
652 QList <QKeySequence> list;
653
654 std::pair<const QKeyBinding *, const QKeyBinding *> range =
655 std::equal_range(QPlatformThemePrivate::keyBindings,
656 QPlatformThemePrivate::keyBindings + QPlatformThemePrivate::numberOfKeyBindings,
657 key, ByStandardKey());
658
659 for (const QKeyBinding *it = range.first; it < range.second; ++it) {
660 if (!(it->platform & platform))
661 continue;
662
663 uint shortcut =
664#if defined(Q_OS_MACX)
665 maybeSwapShortcut(it->shortcut);
666#else
667 it->shortcut;
668#endif
669 if (it->priority > 0)
670 list.prepend(QKeySequence(shortcut));
671 else
672 list.append(QKeySequence(shortcut));
673 }
674
675 return list;
676}
677#endif
678
679/*!
680 Returns the text of a standard \a button.
681
682 \since 5.3
683 \sa QPlatformDialogHelper::StandardButton
684 */
685
686QString QPlatformTheme::standardButtonText(int button) const
687{
688 return QPlatformTheme::defaultStandardButtonText(button);
689}
690
691/*!
692 Returns the mnemonic that should be used for a standard \a button.
693
694 \since 5.9
695 \sa QPlatformDialogHelper::StandardButton
696 */
697
698QKeySequence QPlatformTheme::standardButtonShortcut(int button) const
699{
700 Q_UNUSED(button)
701 return QKeySequence();
702}
703
704QString QPlatformTheme::defaultStandardButtonText(int button)
705{
706 switch (button) {
707 case QPlatformDialogHelper::Ok:
708 return QCoreApplication::translate("QPlatformTheme", "OK");
709 case QPlatformDialogHelper::Save:
710 return QCoreApplication::translate("QPlatformTheme", "Save");
711 case QPlatformDialogHelper::SaveAll:
712 return QCoreApplication::translate("QPlatformTheme", "Save All");
713 case QPlatformDialogHelper::Open:
714 return QCoreApplication::translate("QPlatformTheme", "Open");
715 case QPlatformDialogHelper::Yes:
716 return QCoreApplication::translate("QPlatformTheme", "&Yes");
717 case QPlatformDialogHelper::YesToAll:
718 return QCoreApplication::translate("QPlatformTheme", "Yes to &All");
719 case QPlatformDialogHelper::No:
720 return QCoreApplication::translate("QPlatformTheme", "&No");
721 case QPlatformDialogHelper::NoToAll:
722 return QCoreApplication::translate("QPlatformTheme", "N&o to All");
723 case QPlatformDialogHelper::Abort:
724 return QCoreApplication::translate("QPlatformTheme", "Abort");
725 case QPlatformDialogHelper::Retry:
726 return QCoreApplication::translate("QPlatformTheme", "Retry");
727 case QPlatformDialogHelper::Ignore:
728 return QCoreApplication::translate("QPlatformTheme", "Ignore");
729 case QPlatformDialogHelper::Close:
730 return QCoreApplication::translate("QPlatformTheme", "Close");
731 case QPlatformDialogHelper::Cancel:
732 return QCoreApplication::translate("QPlatformTheme", "Cancel");
733 case QPlatformDialogHelper::Discard:
734 return QCoreApplication::translate("QPlatformTheme", "Discard");
735 case QPlatformDialogHelper::Help:
736 return QCoreApplication::translate("QPlatformTheme", "Help");
737 case QPlatformDialogHelper::Apply:
738 return QCoreApplication::translate("QPlatformTheme", "Apply");
739 case QPlatformDialogHelper::Reset:
740 return QCoreApplication::translate("QPlatformTheme", "Reset");
741 case QPlatformDialogHelper::RestoreDefaults:
742 return QCoreApplication::translate("QPlatformTheme", "Restore Defaults");
743 default:
744 break;
745 }
746 return QString();
747}
748
749QString QPlatformTheme::removeMnemonics(const QString &original)
750{
751 QString returnText(original.size(), 0);
752 int finalDest = 0;
753 int currPos = 0;
754 int l = original.length();
755 while (l) {
756 if (original.at(currPos) == QLatin1Char('&')) {
757 ++currPos;
758 --l;
759 if (l == 0)
760 break;
761 } else if (original.at(currPos) == QLatin1Char('(') && l >= 4 &&
762 original.at(currPos + 1) == QLatin1Char('&') &&
763 original.at(currPos + 2) != QLatin1Char('&') &&
764 original.at(currPos + 3) == QLatin1Char(')')) {
765 /* remove mnemonics its format is "\s*(&X)" */
766 int n = 0;
767 while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
768 ++n;
769 finalDest -= n;
770 currPos += 4;
771 l -= 4;
772 continue;
773 }
774 returnText[finalDest] = original.at(currPos);
775 ++currPos;
776 ++finalDest;
777 --l;
778 }
779 returnText.truncate(finalDest);
780 return returnText;
781}
782
783unsigned QPlatformThemePrivate::currentKeyPlatforms()
784{
785 const uint keyboardScheme = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt();
786 unsigned result = 1u << keyboardScheme;
787#ifndef QT_NO_SHORTCUT
788 if (keyboardScheme == QPlatformTheme::KdeKeyboardScheme
789 || keyboardScheme == QPlatformTheme::GnomeKeyboardScheme
790 || keyboardScheme == QPlatformTheme::CdeKeyboardScheme)
791 result |= KB_X11;
792#endif
793 return result;
794}
795
796QT_END_NAMESPACE
797