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 | |
57 | QT_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 | |
175 | enum 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 | |
185 | const 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 | |
353 | const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding)); |
354 | #endif |
355 | |
356 | QPlatformThemePrivate::QPlatformThemePrivate() |
357 | : systemPalette(nullptr) |
358 | { } |
359 | |
360 | QPlatformThemePrivate::~QPlatformThemePrivate() |
361 | { |
362 | delete systemPalette; |
363 | } |
364 | |
365 | Q_GUI_EXPORT QPalette qt_fusionPalette(); |
366 | |
367 | void QPlatformThemePrivate::initializeSystemPalette() |
368 | { |
369 | Q_ASSERT(!systemPalette); |
370 | systemPalette = new QPalette(qt_fusionPalette()); |
371 | } |
372 | |
373 | QPlatformTheme::QPlatformTheme() |
374 | : d_ptr(new QPlatformThemePrivate) |
375 | { |
376 | |
377 | } |
378 | |
379 | QPlatformTheme::QPlatformTheme(QPlatformThemePrivate *priv) |
380 | : d_ptr(priv) |
381 | { } |
382 | |
383 | QPlatformTheme::~QPlatformTheme() |
384 | { |
385 | |
386 | } |
387 | |
388 | bool QPlatformTheme::usePlatformNativeDialog(DialogType type) const |
389 | { |
390 | Q_UNUSED(type); |
391 | return false; |
392 | } |
393 | |
394 | QPlatformDialogHelper *QPlatformTheme::createPlatformDialogHelper(DialogType type) const |
395 | { |
396 | Q_UNUSED(type); |
397 | return nullptr; |
398 | } |
399 | |
400 | const 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 | |
411 | const QFont *QPlatformTheme::font(Font type) const |
412 | { |
413 | Q_UNUSED(type); |
414 | return nullptr; |
415 | } |
416 | |
417 | QPixmap 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 | |
435 | QIcon 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 | |
443 | QVariant 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 | |
481 | QVariant 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 | |
570 | QPlatformMenuItem *QPlatformTheme::() const |
571 | { |
572 | return nullptr; |
573 | } |
574 | |
575 | QPlatformMenu *QPlatformTheme::() const |
576 | { |
577 | return nullptr; |
578 | } |
579 | |
580 | QPlatformMenuBar *QPlatformTheme::() 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 | */ |
590 | QPlatformSystemTrayIcon *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 | */ |
606 | QIconEngine *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) |
613 | struct 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 | */ |
634 | QList<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 | |
667 | QString 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 | |
680 | QKeySequence QPlatformTheme::standardButtonShortcut(int button) const |
681 | { |
682 | Q_UNUSED(button); |
683 | return QKeySequence(); |
684 | } |
685 | #endif // QT_CONFIG(shortcut) |
686 | |
687 | QString 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 | |
732 | QString 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 | |
766 | unsigned 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 | |
779 | QT_END_NAMESPACE |
780 | |