diff --git a/3rdparty/qxt/CMakeLists.txt b/3rdparty/qxt/CMakeLists.txt new file mode 100644 index 000000000..73954ffc9 --- /dev/null +++ b/3rdparty/qxt/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 2.6) + +set(QXT-SOURCES + qxtglobal.cpp + qxtglobalshortcut.cpp +) + +set(QXT-MOC-HEADERS + qxtglobalshortcut.h +) + +find_package(X11) +include_directories(${X11_INCLUDE_DIR}) + +if(WIN32) + set(QXT-SOURCES ${QXT-SOURCES} qxtglobalshortcut_win.cpp) +elseif(APPLE) + set(QXT-SOURCES ${QXT-SOURCES} qxtglobalshortcut_mac.cpp) +else(WIN32) + set(QXT-SOURCES ${QXT-SOURCES} qxtglobalshortcut_x11.cpp) +endif(WIN32) + +QT4_WRAP_CPP(QXT-SOURCES-MOC ${QXT-MOC-HEADERS}) + +ADD_LIBRARY(qxt STATIC + ${QXT-SOURCES} + ${QXT-SOURCES-MOC} +) diff --git a/3rdparty/qxt/LICENSE b/3rdparty/qxt/LICENSE new file mode 100644 index 000000000..91a9970ff --- /dev/null +++ b/3rdparty/qxt/LICENSE @@ -0,0 +1,89 @@ +Qt Extension Library +Copyright (C) 2007 Qxt Foundation + +------------------- Disclaimer ------------------------------------------------ + +Until the Qxt Foundation is legally established, copyright for the +source code falls back to the original contributor. For information about the +status of the Qxt Foundation, or about the copyright status of any part of Qxt, +contact the Qxt project maintainers at + +Once the Qxt Foundation has been legally established, all contributors must +transfer all copyright interest to the Qxt Foundation before their submissions +will be added to the project. + +------------------- License --------------------------------------------------- + +This library is free software; you can redistribute it and/or modify it +under the terms of the Common Public License, version 1.0, as published by IBM +or under the terms of the GNU Lesser General Public License, version 2.1, +as published by the Free Software Foundation + +This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +FITNESS FOR A PARTICULAR PURPOSE. + +You should have received a copy of the CPL along with this file. +See the LICENSE file and the cpl1.0.txt file included with the source +distribution for more information. If you did not receive a copy of the +license, contact the Qxt Foundation. + +You should have received a copy of the LGPL along with this file. +See the LICENSE file and the lgpl-2.1.txt file included with the source +distribution for more information. If you did not receive a copy of the +license, contact the Qxt Foundation. + +Parts of Qxt depend on Qt 4 and/or other libraries that have their own +licenses. Qxt is independent of these licenses; however, use of these other +libraries is subject to their respective license agreements. + +------------------- Intent ---------------------------------------------------- + +The following section describes the opinions and intent of the Qxt Foundation +with regards to the licensing and use of the Qxt source code and library. In +the event that the CPL is found to be illegal or invalid, or if any application +or clause of the license is subjected to question or abuse, this section is a +general statement of the desired interpretation. + +This section has no legal standing and the statements made here are strictly +subject to the text of the CPL; that is, if this section and the CPL are in +disagreement, the text of the CPL takes precedence. In no way does this +intent grant you any additional rights or impose any additional restrictions. + +If you have questions about licensing, contact the maintainers. + +Qxt is built and supported by open-source enthusiasts. +- Please respect the open-source background of the contributors. The code is + provided for everyone's use; you may not restrict the rights of anyone to + use it. + - No individual may claim ownership of any part of the code. It belongs + to the community. + - You may modify the source code to suit your needs, but these changes + must be made free. If you distribute a modified form of Qxt, you must + also distribute the entire source code of the modified form. + - Digital Rights Management (DRM) puts unfair, unfree restrictions on + users and developers. It is the opposite of Free Software. We can't + stop you from using it, but please don't use the Qxt name for software + restricted by DRM. +- Please respect the time and effort put into the project by the developers. + - If you find Qxt useful, it would be appreciated if you would include + text in your application (for instance, in the About dialog) giving + acknowledgement to Qxt. + - If you make modifications to the source code, you must not call the + modified version "Qxt." It's okay to include "Qxt" in the name, but + anyone who receives the modified version needs to know that it's not + the same as the version distributed by the Qxt Foundation. +- We want everyone to be able to use Qxt without restrictions. + - If you distribute Qxt in compiled binary form, please ensure that + everyone who receives it can get the source code used to create it. + - You are free to use Qxt in closed-source applications as long as you + distribute Qxt in an open-source fashion. This does not require you + to make your entire application open-source. +- The Qxt Foundation is a non-profit, non-political organization. + - Please don't use the Qxt name in any political or semi-political + propaganda or publication. We don't like it. +- Qxt is distributed "as-is," with no warranty. + - If it makes your program crash, your computer blow up, or tiny demons + fly out of your nose, please don't sue us. + diff --git a/3rdparty/qxt/keymapper_x11.h b/3rdparty/qxt/keymapper_x11.h new file mode 100644 index 000000000..dec82853a --- /dev/null +++ b/3rdparty/qxt/keymapper_x11.h @@ -0,0 +1,364 @@ +#ifndef KEYMAPPER_X11_H +#define KEYMAPPER_X11_H + +// (davidsansome) Nicked from qkeymapper_x11.cpp + +#include + +#define XK_MISCELLANY +#define XK_LATIN1 +#define XK_KOREAN +#define XK_XKB_KEYS +#include + +// +// Keyboard event translation +// + +#ifndef XK_ISO_Left_Tab +#define XK_ISO_Left_Tab 0xFE20 +#endif + +#ifndef XK_dead_hook +#define XK_dead_hook 0xFE61 +#endif + +#ifndef XK_dead_horn +#define XK_dead_horn 0xFE62 +#endif + +#ifndef XK_Codeinput +#define XK_Codeinput 0xFF37 +#endif + +#ifndef XK_Kanji_Bangou +#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */ +#endif + +// Fix old X libraries +#ifndef XK_KP_Home +#define XK_KP_Home 0xFF95 +#endif +#ifndef XK_KP_Left +#define XK_KP_Left 0xFF96 +#endif +#ifndef XK_KP_Up +#define XK_KP_Up 0xFF97 +#endif +#ifndef XK_KP_Right +#define XK_KP_Right 0xFF98 +#endif +#ifndef XK_KP_Down +#define XK_KP_Down 0xFF99 +#endif +#ifndef XK_KP_Prior +#define XK_KP_Prior 0xFF9A +#endif +#ifndef XK_KP_Next +#define XK_KP_Next 0xFF9B +#endif +#ifndef XK_KP_End +#define XK_KP_End 0xFF9C +#endif +#ifndef XK_KP_Insert +#define XK_KP_Insert 0xFF9E +#endif +#ifndef XK_KP_Delete +#define XK_KP_Delete 0xFF9F +#endif + +// the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special +// multimedia keys. They are included here as not every system has them. +#define XF86XK_Standby 0x1008FF10 +#define XF86XK_AudioLowerVolume 0x1008FF11 +#define XF86XK_AudioMute 0x1008FF12 +#define XF86XK_AudioRaiseVolume 0x1008FF13 +#define XF86XK_AudioPlay 0x1008FF14 +#define XF86XK_AudioStop 0x1008FF15 +#define XF86XK_AudioPrev 0x1008FF16 +#define XF86XK_AudioNext 0x1008FF17 +#define XF86XK_HomePage 0x1008FF18 +#define XF86XK_Calculator 0x1008FF1D +#define XF86XK_Mail 0x1008FF19 +#define XF86XK_Start 0x1008FF1A +#define XF86XK_Search 0x1008FF1B +#define XF86XK_AudioRecord 0x1008FF1C +#define XF86XK_Back 0x1008FF26 +#define XF86XK_Forward 0x1008FF27 +#define XF86XK_Stop 0x1008FF28 +#define XF86XK_Refresh 0x1008FF29 +#define XF86XK_Favorites 0x1008FF30 +#define XF86XK_AudioPause 0x1008FF31 +#define XF86XK_AudioMedia 0x1008FF32 +#define XF86XK_MyComputer 0x1008FF33 +#define XF86XK_OpenURL 0x1008FF38 +#define XF86XK_Launch0 0x1008FF40 +#define XF86XK_Launch1 0x1008FF41 +#define XF86XK_Launch2 0x1008FF42 +#define XF86XK_Launch3 0x1008FF43 +#define XF86XK_Launch4 0x1008FF44 +#define XF86XK_Launch5 0x1008FF45 +#define XF86XK_Launch6 0x1008FF46 +#define XF86XK_Launch7 0x1008FF47 +#define XF86XK_Launch8 0x1008FF48 +#define XF86XK_Launch9 0x1008FF49 +#define XF86XK_LaunchA 0x1008FF4A +#define XF86XK_LaunchB 0x1008FF4B +#define XF86XK_LaunchC 0x1008FF4C +#define XF86XK_LaunchD 0x1008FF4D +#define XF86XK_LaunchE 0x1008FF4E +#define XF86XK_LaunchF 0x1008FF4F +// end of XF86keysyms.h + +// Special keys used by Qtopia, mapped into the X11 private keypad range. +#define QTOPIAXK_Select 0x11000601 +#define QTOPIAXK_Yes 0x11000602 +#define QTOPIAXK_No 0x11000603 +#define QTOPIAXK_Cancel 0x11000604 +#define QTOPIAXK_Printer 0x11000605 +#define QTOPIAXK_Execute 0x11000606 +#define QTOPIAXK_Sleep 0x11000607 +#define QTOPIAXK_Play 0x11000608 +#define QTOPIAXK_Zoom 0x11000609 +#define QTOPIAXK_Context1 0x1100060A +#define QTOPIAXK_Context2 0x1100060B +#define QTOPIAXK_Context3 0x1100060C +#define QTOPIAXK_Context4 0x1100060D +#define QTOPIAXK_Call 0x1100060E +#define QTOPIAXK_Hangup 0x1100060F +#define QTOPIAXK_Flip 0x11000610 + +// keyboard mapping table +static const unsigned int KeyTbl[] = { + + // misc keys + + XK_Escape, Qt::Key_Escape, + XK_Tab, Qt::Key_Tab, + XK_ISO_Left_Tab, Qt::Key_Backtab, + XK_BackSpace, Qt::Key_Backspace, + XK_Return, Qt::Key_Return, + XK_Insert, Qt::Key_Insert, + XK_Delete, Qt::Key_Delete, + XK_Clear, Qt::Key_Delete, + XK_Pause, Qt::Key_Pause, + XK_Print, Qt::Key_Print, + 0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq + 0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq + + // cursor movement + + XK_Home, Qt::Key_Home, + XK_End, Qt::Key_End, + XK_Left, Qt::Key_Left, + XK_Up, Qt::Key_Up, + XK_Right, Qt::Key_Right, + XK_Down, Qt::Key_Down, + XK_Prior, Qt::Key_PageUp, + XK_Next, Qt::Key_PageDown, + + // modifiers + + XK_Shift_L, Qt::Key_Shift, + XK_Shift_R, Qt::Key_Shift, + XK_Shift_Lock, Qt::Key_Shift, + XK_Control_L, Qt::Key_Control, + XK_Control_R, Qt::Key_Control, + XK_Meta_L, Qt::Key_Meta, + XK_Meta_R, Qt::Key_Meta, + XK_Alt_L, Qt::Key_Alt, + XK_Alt_R, Qt::Key_Alt, + XK_Caps_Lock, Qt::Key_CapsLock, + XK_Num_Lock, Qt::Key_NumLock, + XK_Scroll_Lock, Qt::Key_ScrollLock, + XK_Super_L, Qt::Key_Super_L, + XK_Super_R, Qt::Key_Super_R, + XK_Menu, Qt::Key_Menu, + XK_Hyper_L, Qt::Key_Hyper_L, + XK_Hyper_R, Qt::Key_Hyper_R, + XK_Help, Qt::Key_Help, + 0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab + 0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11) + 0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12) + + // numeric and function keypad keys + + XK_KP_Space, Qt::Key_Space, + XK_KP_Tab, Qt::Key_Tab, + XK_KP_Enter, Qt::Key_Enter, + //XK_KP_F1, Qt::Key_F1, + //XK_KP_F2, Qt::Key_F2, + //XK_KP_F3, Qt::Key_F3, + //XK_KP_F4, Qt::Key_F4, + XK_KP_Home, Qt::Key_Home, + XK_KP_Left, Qt::Key_Left, + XK_KP_Up, Qt::Key_Up, + XK_KP_Right, Qt::Key_Right, + XK_KP_Down, Qt::Key_Down, + XK_KP_Prior, Qt::Key_PageUp, + XK_KP_Next, Qt::Key_PageDown, + XK_KP_End, Qt::Key_End, + XK_KP_Begin, Qt::Key_Clear, + XK_KP_Insert, Qt::Key_Insert, + XK_KP_Delete, Qt::Key_Delete, + XK_KP_Equal, Qt::Key_Equal, + XK_KP_Multiply, Qt::Key_Asterisk, + XK_KP_Add, Qt::Key_Plus, + XK_KP_Separator, Qt::Key_Comma, + XK_KP_Subtract, Qt::Key_Minus, + XK_KP_Decimal, Qt::Key_Period, + XK_KP_Divide, Qt::Key_Slash, + + // International input method support keys + + // International & multi-key character composition + XK_ISO_Level3_Shift, Qt::Key_AltGr, + XK_Multi_key, Qt::Key_Multi_key, + XK_Codeinput, Qt::Key_Codeinput, + XK_SingleCandidate, Qt::Key_SingleCandidate, + XK_MultipleCandidate, Qt::Key_MultipleCandidate, + XK_PreviousCandidate, Qt::Key_PreviousCandidate, + + // Misc Functions + XK_Mode_switch, Qt::Key_Mode_switch, + XK_script_switch, Qt::Key_Mode_switch, + + // Japanese keyboard support + XK_Kanji, Qt::Key_Kanji, + XK_Muhenkan, Qt::Key_Muhenkan, + //XK_Henkan_Mode, Qt::Key_Henkan_Mode, + XK_Henkan_Mode, Qt::Key_Henkan, + XK_Henkan, Qt::Key_Henkan, + XK_Romaji, Qt::Key_Romaji, + XK_Hiragana, Qt::Key_Hiragana, + XK_Katakana, Qt::Key_Katakana, + XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana, + XK_Zenkaku, Qt::Key_Zenkaku, + XK_Hankaku, Qt::Key_Hankaku, + XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku, + XK_Touroku, Qt::Key_Touroku, + XK_Massyo, Qt::Key_Massyo, + XK_Kana_Lock, Qt::Key_Kana_Lock, + XK_Kana_Shift, Qt::Key_Kana_Shift, + XK_Eisu_Shift, Qt::Key_Eisu_Shift, + XK_Eisu_toggle, Qt::Key_Eisu_toggle, + //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou, + //XK_Zen_Koho, Qt::Key_Zen_Koho, + //XK_Mae_Koho, Qt::Key_Mae_Koho, + XK_Kanji_Bangou, Qt::Key_Codeinput, + XK_Zen_Koho, Qt::Key_MultipleCandidate, + XK_Mae_Koho, Qt::Key_PreviousCandidate, + +#ifdef XK_KOREAN + // Korean keyboard support + XK_Hangul, Qt::Key_Hangul, + XK_Hangul_Start, Qt::Key_Hangul_Start, + XK_Hangul_End, Qt::Key_Hangul_End, + XK_Hangul_Hanja, Qt::Key_Hangul_Hanja, + XK_Hangul_Jamo, Qt::Key_Hangul_Jamo, + XK_Hangul_Romaja, Qt::Key_Hangul_Romaja, + //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput, + XK_Hangul_Codeinput, Qt::Key_Codeinput, + XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja, + XK_Hangul_Banja, Qt::Key_Hangul_Banja, + XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja, + XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja, + //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate, + //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate, + //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate, + XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate, + XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate, + XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate, + XK_Hangul_Special, Qt::Key_Hangul_Special, + //XK_Hangul_switch, Qt::Key_Hangul_switch, + XK_Hangul_switch, Qt::Key_Mode_switch, +#endif // XK_KOREAN + + // dead keys + XK_dead_grave, Qt::Key_Dead_Grave, + XK_dead_acute, Qt::Key_Dead_Acute, + XK_dead_circumflex, Qt::Key_Dead_Circumflex, + XK_dead_tilde, Qt::Key_Dead_Tilde, + XK_dead_macron, Qt::Key_Dead_Macron, + XK_dead_breve, Qt::Key_Dead_Breve, + XK_dead_abovedot, Qt::Key_Dead_Abovedot, + XK_dead_diaeresis, Qt::Key_Dead_Diaeresis, + XK_dead_abovering, Qt::Key_Dead_Abovering, + XK_dead_doubleacute, Qt::Key_Dead_Doubleacute, + XK_dead_caron, Qt::Key_Dead_Caron, + XK_dead_cedilla, Qt::Key_Dead_Cedilla, + XK_dead_ogonek, Qt::Key_Dead_Ogonek, + XK_dead_iota, Qt::Key_Dead_Iota, + XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound, + XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound, + XK_dead_belowdot, Qt::Key_Dead_Belowdot, + XK_dead_hook, Qt::Key_Dead_Hook, + XK_dead_horn, Qt::Key_Dead_Horn, + + // Special multimedia keys + // currently only tested with MS internet keyboard + + // browsing keys + XF86XK_Back, Qt::Key_Back, + XF86XK_Forward, Qt::Key_Forward, + XF86XK_Stop, Qt::Key_Stop, + XF86XK_Refresh, Qt::Key_Refresh, + XF86XK_Favorites, Qt::Key_Favorites, + XF86XK_AudioMedia, Qt::Key_LaunchMedia, + XF86XK_OpenURL, Qt::Key_OpenUrl, + XF86XK_HomePage, Qt::Key_HomePage, + XF86XK_Search, Qt::Key_Search, + + // media keys + XF86XK_AudioLowerVolume, Qt::Key_VolumeDown, + XF86XK_AudioMute, Qt::Key_VolumeMute, + XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp, + XF86XK_AudioPlay, Qt::Key_MediaPlay, + XF86XK_AudioStop, Qt::Key_MediaStop, + XF86XK_AudioPrev, Qt::Key_MediaPrevious, + XF86XK_AudioNext, Qt::Key_MediaNext, + XF86XK_AudioRecord, Qt::Key_MediaRecord, + + // launch keys + XF86XK_Mail, Qt::Key_LaunchMail, + XF86XK_MyComputer, Qt::Key_Launch0, + XF86XK_Calculator, Qt::Key_Launch1, + XF86XK_Standby, Qt::Key_Standby, + + XF86XK_Launch0, Qt::Key_Launch2, + XF86XK_Launch1, Qt::Key_Launch3, + XF86XK_Launch2, Qt::Key_Launch4, + XF86XK_Launch3, Qt::Key_Launch5, + XF86XK_Launch4, Qt::Key_Launch6, + XF86XK_Launch5, Qt::Key_Launch7, + XF86XK_Launch6, Qt::Key_Launch8, + XF86XK_Launch7, Qt::Key_Launch9, + XF86XK_Launch8, Qt::Key_LaunchA, + XF86XK_Launch9, Qt::Key_LaunchB, + XF86XK_LaunchA, Qt::Key_LaunchC, + XF86XK_LaunchB, Qt::Key_LaunchD, + XF86XK_LaunchC, Qt::Key_LaunchE, + XF86XK_LaunchD, Qt::Key_LaunchF, + + // Qtopia keys + QTOPIAXK_Select, Qt::Key_Select, + QTOPIAXK_Yes, Qt::Key_Yes, + QTOPIAXK_No, Qt::Key_No, + QTOPIAXK_Cancel, Qt::Key_Cancel, + QTOPIAXK_Printer, Qt::Key_Printer, + QTOPIAXK_Execute, Qt::Key_Execute, + QTOPIAXK_Sleep, Qt::Key_Sleep, + QTOPIAXK_Play, Qt::Key_Play, + QTOPIAXK_Zoom, Qt::Key_Zoom, + QTOPIAXK_Context1, Qt::Key_Context1, + QTOPIAXK_Context2, Qt::Key_Context2, + QTOPIAXK_Context3, Qt::Key_Context3, + QTOPIAXK_Context4, Qt::Key_Context4, + QTOPIAXK_Call, Qt::Key_Call, + QTOPIAXK_Hangup, Qt::Key_Hangup, + QTOPIAXK_Flip, Qt::Key_Flip, + + 0, 0 +}; + +#endif // KEYMAPPER_X11_H diff --git a/3rdparty/qxt/media-keys.patch b/3rdparty/qxt/media-keys.patch new file mode 100644 index 000000000..31e52f3da --- /dev/null +++ b/3rdparty/qxt/media-keys.patch @@ -0,0 +1,432 @@ +diff -ru libqxt-old/src/gui/keymapper_x11.h libqxt/src/gui/keymapper_x11.h +--- libqxt-old/src/gui/keymapper_x11.h 2010-04-21 15:17:56.000000000 +0100 ++++ libqxt/src/gui/keymapper_x11.h 2010-04-21 15:18:16.000000000 +0100 +@@ -0,0 +1,364 @@ ++#ifndef KEYMAPPER_X11_H ++#define KEYMAPPER_X11_H ++ ++// (davidsansome) Nicked from qkeymapper_x11.cpp ++ ++#include ++ ++#define XK_MISCELLANY ++#define XK_LATIN1 ++#define XK_KOREAN ++#define XK_XKB_KEYS ++#include ++ ++// ++// Keyboard event translation ++// ++ ++#ifndef XK_ISO_Left_Tab ++#define XK_ISO_Left_Tab 0xFE20 ++#endif ++ ++#ifndef XK_dead_hook ++#define XK_dead_hook 0xFE61 ++#endif ++ ++#ifndef XK_dead_horn ++#define XK_dead_horn 0xFE62 ++#endif ++ ++#ifndef XK_Codeinput ++#define XK_Codeinput 0xFF37 ++#endif ++ ++#ifndef XK_Kanji_Bangou ++#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */ ++#endif ++ ++// Fix old X libraries ++#ifndef XK_KP_Home ++#define XK_KP_Home 0xFF95 ++#endif ++#ifndef XK_KP_Left ++#define XK_KP_Left 0xFF96 ++#endif ++#ifndef XK_KP_Up ++#define XK_KP_Up 0xFF97 ++#endif ++#ifndef XK_KP_Right ++#define XK_KP_Right 0xFF98 ++#endif ++#ifndef XK_KP_Down ++#define XK_KP_Down 0xFF99 ++#endif ++#ifndef XK_KP_Prior ++#define XK_KP_Prior 0xFF9A ++#endif ++#ifndef XK_KP_Next ++#define XK_KP_Next 0xFF9B ++#endif ++#ifndef XK_KP_End ++#define XK_KP_End 0xFF9C ++#endif ++#ifndef XK_KP_Insert ++#define XK_KP_Insert 0xFF9E ++#endif ++#ifndef XK_KP_Delete ++#define XK_KP_Delete 0xFF9F ++#endif ++ ++// the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special ++// multimedia keys. They are included here as not every system has them. ++#define XF86XK_Standby 0x1008FF10 ++#define XF86XK_AudioLowerVolume 0x1008FF11 ++#define XF86XK_AudioMute 0x1008FF12 ++#define XF86XK_AudioRaiseVolume 0x1008FF13 ++#define XF86XK_AudioPlay 0x1008FF14 ++#define XF86XK_AudioStop 0x1008FF15 ++#define XF86XK_AudioPrev 0x1008FF16 ++#define XF86XK_AudioNext 0x1008FF17 ++#define XF86XK_HomePage 0x1008FF18 ++#define XF86XK_Calculator 0x1008FF1D ++#define XF86XK_Mail 0x1008FF19 ++#define XF86XK_Start 0x1008FF1A ++#define XF86XK_Search 0x1008FF1B ++#define XF86XK_AudioRecord 0x1008FF1C ++#define XF86XK_Back 0x1008FF26 ++#define XF86XK_Forward 0x1008FF27 ++#define XF86XK_Stop 0x1008FF28 ++#define XF86XK_Refresh 0x1008FF29 ++#define XF86XK_Favorites 0x1008FF30 ++#define XF86XK_AudioPause 0x1008FF31 ++#define XF86XK_AudioMedia 0x1008FF32 ++#define XF86XK_MyComputer 0x1008FF33 ++#define XF86XK_OpenURL 0x1008FF38 ++#define XF86XK_Launch0 0x1008FF40 ++#define XF86XK_Launch1 0x1008FF41 ++#define XF86XK_Launch2 0x1008FF42 ++#define XF86XK_Launch3 0x1008FF43 ++#define XF86XK_Launch4 0x1008FF44 ++#define XF86XK_Launch5 0x1008FF45 ++#define XF86XK_Launch6 0x1008FF46 ++#define XF86XK_Launch7 0x1008FF47 ++#define XF86XK_Launch8 0x1008FF48 ++#define XF86XK_Launch9 0x1008FF49 ++#define XF86XK_LaunchA 0x1008FF4A ++#define XF86XK_LaunchB 0x1008FF4B ++#define XF86XK_LaunchC 0x1008FF4C ++#define XF86XK_LaunchD 0x1008FF4D ++#define XF86XK_LaunchE 0x1008FF4E ++#define XF86XK_LaunchF 0x1008FF4F ++// end of XF86keysyms.h ++ ++// Special keys used by Qtopia, mapped into the X11 private keypad range. ++#define QTOPIAXK_Select 0x11000601 ++#define QTOPIAXK_Yes 0x11000602 ++#define QTOPIAXK_No 0x11000603 ++#define QTOPIAXK_Cancel 0x11000604 ++#define QTOPIAXK_Printer 0x11000605 ++#define QTOPIAXK_Execute 0x11000606 ++#define QTOPIAXK_Sleep 0x11000607 ++#define QTOPIAXK_Play 0x11000608 ++#define QTOPIAXK_Zoom 0x11000609 ++#define QTOPIAXK_Context1 0x1100060A ++#define QTOPIAXK_Context2 0x1100060B ++#define QTOPIAXK_Context3 0x1100060C ++#define QTOPIAXK_Context4 0x1100060D ++#define QTOPIAXK_Call 0x1100060E ++#define QTOPIAXK_Hangup 0x1100060F ++#define QTOPIAXK_Flip 0x11000610 ++ ++// keyboard mapping table ++static const unsigned int KeyTbl[] = { ++ ++ // misc keys ++ ++ XK_Escape, Qt::Key_Escape, ++ XK_Tab, Qt::Key_Tab, ++ XK_ISO_Left_Tab, Qt::Key_Backtab, ++ XK_BackSpace, Qt::Key_Backspace, ++ XK_Return, Qt::Key_Return, ++ XK_Insert, Qt::Key_Insert, ++ XK_Delete, Qt::Key_Delete, ++ XK_Clear, Qt::Key_Delete, ++ XK_Pause, Qt::Key_Pause, ++ XK_Print, Qt::Key_Print, ++ 0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq ++ 0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq ++ ++ // cursor movement ++ ++ XK_Home, Qt::Key_Home, ++ XK_End, Qt::Key_End, ++ XK_Left, Qt::Key_Left, ++ XK_Up, Qt::Key_Up, ++ XK_Right, Qt::Key_Right, ++ XK_Down, Qt::Key_Down, ++ XK_Prior, Qt::Key_PageUp, ++ XK_Next, Qt::Key_PageDown, ++ ++ // modifiers ++ ++ XK_Shift_L, Qt::Key_Shift, ++ XK_Shift_R, Qt::Key_Shift, ++ XK_Shift_Lock, Qt::Key_Shift, ++ XK_Control_L, Qt::Key_Control, ++ XK_Control_R, Qt::Key_Control, ++ XK_Meta_L, Qt::Key_Meta, ++ XK_Meta_R, Qt::Key_Meta, ++ XK_Alt_L, Qt::Key_Alt, ++ XK_Alt_R, Qt::Key_Alt, ++ XK_Caps_Lock, Qt::Key_CapsLock, ++ XK_Num_Lock, Qt::Key_NumLock, ++ XK_Scroll_Lock, Qt::Key_ScrollLock, ++ XK_Super_L, Qt::Key_Super_L, ++ XK_Super_R, Qt::Key_Super_R, ++ XK_Menu, Qt::Key_Menu, ++ XK_Hyper_L, Qt::Key_Hyper_L, ++ XK_Hyper_R, Qt::Key_Hyper_R, ++ XK_Help, Qt::Key_Help, ++ 0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab ++ 0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11) ++ 0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12) ++ ++ // numeric and function keypad keys ++ ++ XK_KP_Space, Qt::Key_Space, ++ XK_KP_Tab, Qt::Key_Tab, ++ XK_KP_Enter, Qt::Key_Enter, ++ //XK_KP_F1, Qt::Key_F1, ++ //XK_KP_F2, Qt::Key_F2, ++ //XK_KP_F3, Qt::Key_F3, ++ //XK_KP_F4, Qt::Key_F4, ++ XK_KP_Home, Qt::Key_Home, ++ XK_KP_Left, Qt::Key_Left, ++ XK_KP_Up, Qt::Key_Up, ++ XK_KP_Right, Qt::Key_Right, ++ XK_KP_Down, Qt::Key_Down, ++ XK_KP_Prior, Qt::Key_PageUp, ++ XK_KP_Next, Qt::Key_PageDown, ++ XK_KP_End, Qt::Key_End, ++ XK_KP_Begin, Qt::Key_Clear, ++ XK_KP_Insert, Qt::Key_Insert, ++ XK_KP_Delete, Qt::Key_Delete, ++ XK_KP_Equal, Qt::Key_Equal, ++ XK_KP_Multiply, Qt::Key_Asterisk, ++ XK_KP_Add, Qt::Key_Plus, ++ XK_KP_Separator, Qt::Key_Comma, ++ XK_KP_Subtract, Qt::Key_Minus, ++ XK_KP_Decimal, Qt::Key_Period, ++ XK_KP_Divide, Qt::Key_Slash, ++ ++ // International input method support keys ++ ++ // International & multi-key character composition ++ XK_ISO_Level3_Shift, Qt::Key_AltGr, ++ XK_Multi_key, Qt::Key_Multi_key, ++ XK_Codeinput, Qt::Key_Codeinput, ++ XK_SingleCandidate, Qt::Key_SingleCandidate, ++ XK_MultipleCandidate, Qt::Key_MultipleCandidate, ++ XK_PreviousCandidate, Qt::Key_PreviousCandidate, ++ ++ // Misc Functions ++ XK_Mode_switch, Qt::Key_Mode_switch, ++ XK_script_switch, Qt::Key_Mode_switch, ++ ++ // Japanese keyboard support ++ XK_Kanji, Qt::Key_Kanji, ++ XK_Muhenkan, Qt::Key_Muhenkan, ++ //XK_Henkan_Mode, Qt::Key_Henkan_Mode, ++ XK_Henkan_Mode, Qt::Key_Henkan, ++ XK_Henkan, Qt::Key_Henkan, ++ XK_Romaji, Qt::Key_Romaji, ++ XK_Hiragana, Qt::Key_Hiragana, ++ XK_Katakana, Qt::Key_Katakana, ++ XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana, ++ XK_Zenkaku, Qt::Key_Zenkaku, ++ XK_Hankaku, Qt::Key_Hankaku, ++ XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku, ++ XK_Touroku, Qt::Key_Touroku, ++ XK_Massyo, Qt::Key_Massyo, ++ XK_Kana_Lock, Qt::Key_Kana_Lock, ++ XK_Kana_Shift, Qt::Key_Kana_Shift, ++ XK_Eisu_Shift, Qt::Key_Eisu_Shift, ++ XK_Eisu_toggle, Qt::Key_Eisu_toggle, ++ //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou, ++ //XK_Zen_Koho, Qt::Key_Zen_Koho, ++ //XK_Mae_Koho, Qt::Key_Mae_Koho, ++ XK_Kanji_Bangou, Qt::Key_Codeinput, ++ XK_Zen_Koho, Qt::Key_MultipleCandidate, ++ XK_Mae_Koho, Qt::Key_PreviousCandidate, ++ ++#ifdef XK_KOREAN ++ // Korean keyboard support ++ XK_Hangul, Qt::Key_Hangul, ++ XK_Hangul_Start, Qt::Key_Hangul_Start, ++ XK_Hangul_End, Qt::Key_Hangul_End, ++ XK_Hangul_Hanja, Qt::Key_Hangul_Hanja, ++ XK_Hangul_Jamo, Qt::Key_Hangul_Jamo, ++ XK_Hangul_Romaja, Qt::Key_Hangul_Romaja, ++ //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput, ++ XK_Hangul_Codeinput, Qt::Key_Codeinput, ++ XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja, ++ XK_Hangul_Banja, Qt::Key_Hangul_Banja, ++ XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja, ++ XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja, ++ //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate, ++ //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate, ++ //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate, ++ XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate, ++ XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate, ++ XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate, ++ XK_Hangul_Special, Qt::Key_Hangul_Special, ++ //XK_Hangul_switch, Qt::Key_Hangul_switch, ++ XK_Hangul_switch, Qt::Key_Mode_switch, ++#endif // XK_KOREAN ++ ++ // dead keys ++ XK_dead_grave, Qt::Key_Dead_Grave, ++ XK_dead_acute, Qt::Key_Dead_Acute, ++ XK_dead_circumflex, Qt::Key_Dead_Circumflex, ++ XK_dead_tilde, Qt::Key_Dead_Tilde, ++ XK_dead_macron, Qt::Key_Dead_Macron, ++ XK_dead_breve, Qt::Key_Dead_Breve, ++ XK_dead_abovedot, Qt::Key_Dead_Abovedot, ++ XK_dead_diaeresis, Qt::Key_Dead_Diaeresis, ++ XK_dead_abovering, Qt::Key_Dead_Abovering, ++ XK_dead_doubleacute, Qt::Key_Dead_Doubleacute, ++ XK_dead_caron, Qt::Key_Dead_Caron, ++ XK_dead_cedilla, Qt::Key_Dead_Cedilla, ++ XK_dead_ogonek, Qt::Key_Dead_Ogonek, ++ XK_dead_iota, Qt::Key_Dead_Iota, ++ XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound, ++ XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound, ++ XK_dead_belowdot, Qt::Key_Dead_Belowdot, ++ XK_dead_hook, Qt::Key_Dead_Hook, ++ XK_dead_horn, Qt::Key_Dead_Horn, ++ ++ // Special multimedia keys ++ // currently only tested with MS internet keyboard ++ ++ // browsing keys ++ XF86XK_Back, Qt::Key_Back, ++ XF86XK_Forward, Qt::Key_Forward, ++ XF86XK_Stop, Qt::Key_Stop, ++ XF86XK_Refresh, Qt::Key_Refresh, ++ XF86XK_Favorites, Qt::Key_Favorites, ++ XF86XK_AudioMedia, Qt::Key_LaunchMedia, ++ XF86XK_OpenURL, Qt::Key_OpenUrl, ++ XF86XK_HomePage, Qt::Key_HomePage, ++ XF86XK_Search, Qt::Key_Search, ++ ++ // media keys ++ XF86XK_AudioLowerVolume, Qt::Key_VolumeDown, ++ XF86XK_AudioMute, Qt::Key_VolumeMute, ++ XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp, ++ XF86XK_AudioPlay, Qt::Key_MediaPlay, ++ XF86XK_AudioStop, Qt::Key_MediaStop, ++ XF86XK_AudioPrev, Qt::Key_MediaPrevious, ++ XF86XK_AudioNext, Qt::Key_MediaNext, ++ XF86XK_AudioRecord, Qt::Key_MediaRecord, ++ ++ // launch keys ++ XF86XK_Mail, Qt::Key_LaunchMail, ++ XF86XK_MyComputer, Qt::Key_Launch0, ++ XF86XK_Calculator, Qt::Key_Launch1, ++ XF86XK_Standby, Qt::Key_Standby, ++ ++ XF86XK_Launch0, Qt::Key_Launch2, ++ XF86XK_Launch1, Qt::Key_Launch3, ++ XF86XK_Launch2, Qt::Key_Launch4, ++ XF86XK_Launch3, Qt::Key_Launch5, ++ XF86XK_Launch4, Qt::Key_Launch6, ++ XF86XK_Launch5, Qt::Key_Launch7, ++ XF86XK_Launch6, Qt::Key_Launch8, ++ XF86XK_Launch7, Qt::Key_Launch9, ++ XF86XK_Launch8, Qt::Key_LaunchA, ++ XF86XK_Launch9, Qt::Key_LaunchB, ++ XF86XK_LaunchA, Qt::Key_LaunchC, ++ XF86XK_LaunchB, Qt::Key_LaunchD, ++ XF86XK_LaunchC, Qt::Key_LaunchE, ++ XF86XK_LaunchD, Qt::Key_LaunchF, ++ ++ // Qtopia keys ++ QTOPIAXK_Select, Qt::Key_Select, ++ QTOPIAXK_Yes, Qt::Key_Yes, ++ QTOPIAXK_No, Qt::Key_No, ++ QTOPIAXK_Cancel, Qt::Key_Cancel, ++ QTOPIAXK_Printer, Qt::Key_Printer, ++ QTOPIAXK_Execute, Qt::Key_Execute, ++ QTOPIAXK_Sleep, Qt::Key_Sleep, ++ QTOPIAXK_Play, Qt::Key_Play, ++ QTOPIAXK_Zoom, Qt::Key_Zoom, ++ QTOPIAXK_Context1, Qt::Key_Context1, ++ QTOPIAXK_Context2, Qt::Key_Context2, ++ QTOPIAXK_Context3, Qt::Key_Context3, ++ QTOPIAXK_Context4, Qt::Key_Context4, ++ QTOPIAXK_Call, Qt::Key_Call, ++ QTOPIAXK_Hangup, Qt::Key_Hangup, ++ QTOPIAXK_Flip, Qt::Key_Flip, ++ ++ 0, 0 ++}; ++ ++#endif // KEYMAPPER_X11_H +diff -ru libqxt-old/src/gui/qxtglobalshortcut_win.cpp libqxt/src/gui/qxtglobalshortcut_win.cpp +--- libqxt-old/src/gui/qxtglobalshortcut_win.cpp 2010-04-21 15:17:56.000000000 +0100 ++++ libqxt/src/gui/qxtglobalshortcut_win.cpp 2010-04-21 15:18:16.000000000 +0100 +@@ -156,6 +156,21 @@ + case Qt::Key_Slash: + return VK_DIVIDE; + ++ case Qt::Key_MediaNext: ++ return VK_MEDIA_NEXT_TRACK; ++ case Qt::Key_MediaPrevious: ++ return VK_MEDIA_PREV_TRACK; ++ case Qt::Key_MediaStop: ++ return VK_MEDIA_STOP; ++ case Qt::Key_MediaPlay: ++ return VK_MEDIA_PLAY_PAUSE; ++ case Qt::Key_VolumeDown: ++ return VK_VOLUME_DOWN; ++ case Qt::Key_VolumeUp: ++ return VK_VOLUME_UP; ++ case Qt::Key_VolumeMute: ++ return VK_VOLUME_MUTE; ++ + // numbers + case Qt::Key_0: + case Qt::Key_1: +diff -ru libqxt-old/src/gui/qxtglobalshortcut_x11.cpp libqxt/src/gui/qxtglobalshortcut_x11.cpp +--- libqxt-old/src/gui/qxtglobalshortcut_x11.cpp 2010-04-21 15:17:56.000000000 +0100 ++++ libqxt/src/gui/qxtglobalshortcut_x11.cpp 2010-04-21 15:18:16.000000000 +0100 +@@ -26,6 +26,8 @@ + #include + #include + ++#include "keymapper_x11.h" ++ + static int (*original_x_errhandler)(Display* display, XErrorEvent* event); + + static int qxt_x_errhandler(Display* display, XErrorEvent *event) +@@ -81,8 +83,25 @@ + + quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) + { ++ // (davidsansome) Try the table from QKeyMapper first - this seems to be ++ // the only way to get Keysyms for the media keys. ++ unsigned int keysym = 0; ++ int i = 0; ++ while (KeyTbl[i]) { ++ if (KeyTbl[i+1] == static_cast(key)) { ++ keysym = KeyTbl[i]; ++ break; ++ } ++ i += 2; ++ } ++ ++ // If that didn't work then fall back on XStringToKeysym ++ if (!keysym) { ++ keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data()); ++ } ++ + Display* display = QX11Info::display(); +- return XKeysymToKeycode(display, XStringToKeysym(QKeySequence(key).toString().toLatin1().data())); ++ return XKeysymToKeycode(display, keysym); + } + + bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) diff --git a/3rdparty/qxt/meta-modifier.patch b/3rdparty/qxt/meta-modifier.patch new file mode 100644 index 000000000..f77b97a57 --- /dev/null +++ b/3rdparty/qxt/meta-modifier.patch @@ -0,0 +1,15 @@ +Index: qxtglobalshortcut_x11.cpp +=================================================================== +--- qxtglobalshortcut_x11.cpp (revision 1208) ++++ qxtglobalshortcut_x11.cpp (working copy) +@@ -74,8 +74,9 @@ + native |= ControlMask; + if (modifiers & Qt::AltModifier) + native |= Mod1Mask; ++ if (modifiers & Qt::MetaModifier) ++ native |= Mod4Mask; + // TODO: resolve these? +- //if (modifiers & Qt::MetaModifier) + //if (modifiers & Qt::KeypadModifier) + //if (modifiers & Qt::GroupSwitchModifier) + return native; diff --git a/3rdparty/qxt/qxtglobal.cpp b/3rdparty/qxt/qxtglobal.cpp new file mode 100644 index 000000000..fe7b9e782 --- /dev/null +++ b/3rdparty/qxt/qxtglobal.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtCore module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ + +#include "qxtglobal.h" + +/*! + \headerfile + \title Global Qxt Declarations + \inmodule QxtCore + + \brief The header provides basic declarations and + is included by all other Qxt headers. + */ + +/*! + \macro QXT_VERSION + \relates + + This macro expands a numeric value of the form 0xMMNNPP (MM = + major, NN = minor, PP = patch) that specifies Qxt's version + number. For example, if you compile your application against Qxt + 0.4.0, the QXT_VERSION macro will expand to 0x000400. + + You can use QXT_VERSION to use the latest Qt features where + available. For example: + \code + #if QXT_VERSION >= 0x000400 + qxtTabWidget->setTabMovementMode(QxtTabWidget::InPlaceMovement); + #endif + \endcode + + \sa QXT_VERSION_STR, qxtVersion() + */ + +/*! + \macro QXT_VERSION_STR + \relates + + This macro expands to a string that specifies Qxt's version number + (for example, "0.4.0"). This is the version against which the + application is compiled. + + \sa qxtVersion(), QXT_VERSION + */ + +/*! + \relates + + Returns the version number of Qxt at run-time as a string (for + example, "0.4.0"). This may be a different version than the + version the application was compiled against. + + \sa QXT_VERSION_STR + */ +const char* qxtVersion() +{ + return QXT_VERSION_STR; +} + +/*! +\headerfile +\title The Qxt private implementation +\inmodule QxtCore + +\brief The header provides tools for hiding +details of a class. + +Application code generally doesn't have to be concerned about hiding its +implementation details, but when writing library code it is important to +maintain a constant interface, both source and binary. Maintaining a constant +source interface is easy enough, but keeping the binary interface constant +means moving implementation details into a private class. The PIMPL, or +d-pointer, idiom is a common method of implementing this separation. QxtPimpl +offers a convenient way to connect the public and private sides of your class. + +\section1 Getting Started +Before you declare the public class, you need to make a forward declaration +of the private class. The private class must have the same name as the public +class, followed by the word Private. For example, a class named MyTest would +declare the private class with: +\code +class MyTestPrivate; +\endcode + +\section1 The Public Class +Generally, you shouldn't keep any data members in the public class without a +good reason. Functions that are part of the public interface should be declared +in the public class, and functions that need to be available to subclasses (for +calling or overriding) should be in the protected section of the public class. +To connect the private class to the public class, include the +QXT_DECLARE_PRIVATE macro in the private section of the public class. In the +example above, the private class is connected as follows: +\code +private: + QXT_DECLARE_PRIVATE(MyTest) +\endcode + +Additionally, you must include the QXT_INIT_PRIVATE macro in the public class's +constructor. Continuing with the MyTest example, your constructor might look +like this: +\code +MyTest::MyTest() { + // initialization + QXT_INIT_PRIVATE(MyTest); +} +\endcode + +\section1 The Private Class +As mentioned above, data members should usually be kept in the private class. +This allows the memory layout of the private class to change without breaking +binary compatibility for the public class. Functions that exist only as +implementation details, or functions that need access to private data members, +should be implemented here. + +To define the private class, inherit from the template QxtPrivate class, and +include the QXT_DECLARE_PUBLIC macro in its public section. The template +parameter should be the name of the public class. For example: +\code +class MyTestPrivate : public QxtPrivate { +public: + MyTestPrivate(); + QXT_DECLARE_PUBLIC(MyTest) +}; +\endcode + +\section1 Accessing Private Members +Use the qxt_d() function (actually a function-like object) from functions in +the public class to access the private class. Similarly, functions in the +private class can invoke functions in the public class by using the qxt_p() +function (this one's actually a function). + +For example, assume that MyTest has methods named getFoobar and doBaz(), +and MyTestPrivate has a member named foobar and a method named doQuux(). +The code might resemble this example: +\code +int MyTest::getFoobar() { + return qxt_d().foobar; +} + +void MyTestPrivate::doQuux() { + qxt_p().doBaz(foobar); +} +\endcode +*/ + +/*! + * \macro QXT_DECLARE_PRIVATE(PUB) + * \relates + * Declares that a public class has a related private class. + * + * This shuold be put in the private section of the public class. The parameter is the name of the public class. + */ + +/*! + * \macro QXT_DECLARE_PUBLIC(PUB) + * \relates + * Declares that a private class has a related public class. + * + * This may be put anywhere in the declaration of the private class. The parameter is the name of the public class. + */ + +/*! + * \macro QXT_INIT_PRIVATE(PUB) + * \relates + * Initializes resources owned by the private class. + * + * This should be called from the public class's constructor, + * before qxt_d() is used for the first time. The parameter is the name of the public class. + */ + +/*! + * \macro QXT_D(PUB) + * \relates + * Returns a reference in the current scope named "d" to the private class. + * + * This function is only available in a class using \a QXT_DECLARE_PRIVATE. + */ + +/*! + * \macro QXT_P(PUB) + * \relates + * Creates a reference in the current scope named "q" to the public class. + * + * This macro only works in a class using \a QXT_DECLARE_PUBLIC. + */ + +/*! + * \fn QxtPrivate& PUB::qxt_d() + * \relates + * Returns a reference to the private class. + * + * This function is only available in a class using \a QXT_DECLARE_PRIVATE. + */ + +/*! + * \fn const QxtPrivate& PUB::qxt_d() const + * \relates + * Returns a const reference to the private class. + * + * This function is only available in a class using \a QXT_DECLARE_PRIVATE. + * This overload will be automatically used in const functions. + */ + +/*! + * \fn PUB& QxtPrivate::qxt_p() + * \relates + * Returns a reference to the public class. + * + * This function is only available in a class using \a QXT_DECLARE_PUBLIC. + */ + +/*! + * \fn const PUB& QxtPrivate::qxt_p() const + * \relates + * Returns a const reference to the public class. + * + * This function is only available in a class using \a QXT_DECLARE_PUBLIC. + * This overload will be automatically used in const functions. + */ diff --git a/3rdparty/qxt/qxtglobal.h b/3rdparty/qxt/qxtglobal.h new file mode 100644 index 000000000..038ceafe9 --- /dev/null +++ b/3rdparty/qxt/qxtglobal.h @@ -0,0 +1,207 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtCore module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ + +#ifndef QXTGLOBAL_H +#define QXTGLOBAL_H + +#include + +#define QXT_VERSION 0x000600 +#define QXT_VERSION_STR "0.6.0" + +//--------------------------global macros------------------------------ + +#ifndef QXT_NO_MACROS + +#endif // QXT_NO_MACROS + +//--------------------------export macros------------------------------ + +#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE + +#if !defined(QXT_STATIC) +# if defined(BUILD_QXT_CORE) +# define QXT_CORE_EXPORT Q_DECL_EXPORT +# else +# define QXT_CORE_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_CORE_EXPORT +#endif // BUILD_QXT_CORE + +#if !defined(QXT_STATIC) +# if defined(BUILD_QXT_GUI) +# define QXT_GUI_EXPORT Q_DECL_EXPORT +# else +# define QXT_GUI_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_GUI_EXPORT +#endif // BUILD_QXT_GUI + +#if !defined(QXT_STATIC) +# if defined(BUILD_QXT_NETWORK) +# define QXT_NETWORK_EXPORT Q_DECL_EXPORT +# else +# define QXT_NETWORK_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_NETWORK_EXPORT +#endif // BUILD_QXT_NETWORK + +#if !defined(QXT_STATIC) +# if defined(BUILD_QXT_SQL) +# define QXT_SQL_EXPORT Q_DECL_EXPORT +# else +# define QXT_SQL_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_SQL_EXPORT +#endif // BUILD_QXT_SQL + +#if !defined(QXT_STATIC) +# if defined(BUILD_QXT_WEB) +# define QXT_WEB_EXPORT Q_DECL_EXPORT +# else +# define QXT_WEB_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_WEB_EXPORT +#endif // BUILD_QXT_WEB + +#if !defined(QXT_STATIC) +# if defined(BUILD_QXT_BERKELEY) +# define QXT_BERKELEY_EXPORT Q_DECL_EXPORT +# else +# define QXT_BERKELEY_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_BERKELEY_EXPORT +#endif // BUILD_QXT_BERKELEY + +#if !defined(QXT_STATIC) +# if defined(BUILD_QXT_ZEROCONF) +# define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT +# else +# define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT +# endif +#else +# define QXT_ZEROCONF_EXPORT +#endif // QXT_ZEROCONF_EXPORT + +#if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB || defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF +# define BUILD_QXT +#endif + +QXT_CORE_EXPORT const char* qxtVersion(); + +#ifndef QT_BEGIN_NAMESPACE +#define QT_BEGIN_NAMESPACE +#endif + +#ifndef QT_END_NAMESPACE +#define QT_END_NAMESPACE +#endif + +#ifndef QT_FORWARD_DECLARE_CLASS +#define QT_FORWARD_DECLARE_CLASS(Class) class Class; +#endif + +/**************************************************************************** +** This file is derived from code bearing the following notice: +** The sole author of this file, Adam Higerd, has explicitly disclaimed all +** copyright interest and protection for the content within. This file has +** been placed in the public domain according to United States copyright +** statute and case law. In jurisdictions where this public domain dedication +** is not legally recognized, anyone who receives a copy of this file is +** permitted to use, modify, duplicate, and redistribute this file, in whole +** or in part, with no restrictions or conditions. In these jurisdictions, +** this file shall be copyright (C) 2006-2008 by Adam Higerd. +****************************************************************************/ + +#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d; +#define QXT_DECLARE_PUBLIC(PUB) friend class PUB; +#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this); +#define QXT_D(PUB) PUB##Private& d = qxt_d() +#define QXT_P(PUB) PUB& p = qxt_p() + +template +class QxtPrivate +{ +public: + virtual ~QxtPrivate() + {} + inline void QXT_setPublic(PUB* pub) + { + qxt_p_ptr = pub; + } + +protected: + inline PUB& qxt_p() + { + return *qxt_p_ptr; + } + inline const PUB& qxt_p() const + { + return *qxt_p_ptr; + } + +private: + PUB* qxt_p_ptr; +}; + +template +class QxtPrivateInterface +{ + friend class QxtPrivate; +public: + QxtPrivateInterface() + { + pvt = new PVT; + } + ~QxtPrivateInterface() + { + delete pvt; + } + + inline void setPublic(PUB* pub) + { + pvt->QXT_setPublic(pub); + } + inline PVT& operator()() + { + return *static_cast(pvt); + } + inline const PVT& operator()() const + { + return *static_cast(pvt); + } +private: + QxtPrivateInterface(const QxtPrivateInterface&) { } + QxtPrivateInterface& operator=(const QxtPrivateInterface&) { } + QxtPrivate* pvt; +}; + +#endif // QXT_GLOBAL diff --git a/3rdparty/qxt/qxtglobalshortcut.cpp b/3rdparty/qxt/qxtglobalshortcut.cpp new file mode 100644 index 000000000..ef378f965 --- /dev/null +++ b/3rdparty/qxt/qxtglobalshortcut.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtGui module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ +#include "qxtglobalshortcut.h" +#include "qxtglobalshortcut_p.h" +#include +#include + +bool QxtGlobalShortcutPrivate::error = false; +int QxtGlobalShortcutPrivate::ref = 0; +QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0; +QHash, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts; + +QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier) +{ + if (!ref++) + prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter); +} + +QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate() +{ + if (!--ref) + QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter); +} + +bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut) +{ + Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier; + key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]); + mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods); + const quint32 nativeKey = nativeKeycode(key); + const quint32 nativeMods = nativeModifiers(mods); + const bool res = registerShortcut(nativeKey, nativeMods); + shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p()); + if (!res) + qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString(); + return res; +} + +bool QxtGlobalShortcutPrivate::unsetShortcut() +{ + const quint32 nativeKey = nativeKeycode(key); + const quint32 nativeMods = nativeModifiers(mods); + const bool res = unregisterShortcut(nativeKey, nativeMods); + shortcuts.remove(qMakePair(nativeKey, nativeMods)); + if (!res) + qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString(); + key = Qt::Key(0); + mods = Qt::KeyboardModifiers(0); + return res; +} + +void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods) +{ + QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods)); + if (shortcut && shortcut->isEnabled()) + emit shortcut->activated(); +} + +/*! + \class QxtGlobalShortcut + \inmodule QxtGui + \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey". + + A global shortcut triggers even if the application is not active. This + makes it easy to implement applications that react to certain shortcuts + still if some other application is active or if the application is for + example minimized to the system tray. + + Example usage: + \code + QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window); + connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility())); + shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12")); + \endcode + + \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication. + */ + +/*! + \fn QxtGlobalShortcut::activated() + + This signal is emitted when the user types the shortcut's key sequence. + + \sa shortcut + */ + +/*! + Constructs a new QxtGlobalShortcut with \a parent. + */ +QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent) + : QObject(parent) +{ + QXT_INIT_PRIVATE(QxtGlobalShortcut); +} + +/*! + Constructs a new QxtGlobalShortcut with \a shortcut and \a parent. + */ +QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent) + : QObject(parent) +{ + QXT_INIT_PRIVATE(QxtGlobalShortcut); + setShortcut(shortcut); +} + +/*! + Destructs the QxtGlobalShortcut. + */ +QxtGlobalShortcut::~QxtGlobalShortcut() +{ + if (qxt_d().key != 0) + qxt_d().unsetShortcut(); +} + +/*! + \property QxtGlobalShortcut::shortcut + \brief the shortcut key sequence + + \bold {Note:} Notice that corresponding key press and release events are not + delivered for registered global shortcuts even if they are disabled. + Also, comma separated key sequences are not supported. + Only the first part is used: + + \code + qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B")); + Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A")); + \endcode + */ +QKeySequence QxtGlobalShortcut::shortcut() const +{ + return QKeySequence(qxt_d().key | qxt_d().mods); +} + +bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut) +{ + if (qxt_d().key != 0) + qxt_d().unsetShortcut(); + return qxt_d().setShortcut(shortcut); +} + +/*! + \property QxtGlobalShortcut::enabled + \brief whether the shortcut is enabled + + A disabled shortcut does not get activated. + + The default value is \c true. + + \sa setDisabled() + */ +bool QxtGlobalShortcut::isEnabled() const +{ + return qxt_d().enabled; +} + +void QxtGlobalShortcut::setEnabled(bool enabled) +{ + qxt_d().enabled = enabled; +} + +/*! + Sets the shortcut \a disabled. + + \sa enabled + */ +void QxtGlobalShortcut::setDisabled(bool disabled) +{ + qxt_d().enabled = !disabled; +} diff --git a/3rdparty/qxt/qxtglobalshortcut.h b/3rdparty/qxt/qxtglobalshortcut.h new file mode 100644 index 000000000..a97ba2ddb --- /dev/null +++ b/3rdparty/qxt/qxtglobalshortcut.h @@ -0,0 +1,58 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtGui module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ +#ifndef QXTGLOBALSHORTCUT_H +#define QXTGLOBALSHORTCUT_H + +#include "qxtglobal.h" +#include +#include +class QxtGlobalShortcutPrivate; + +class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject +{ + Q_OBJECT + QXT_DECLARE_PRIVATE(QxtGlobalShortcut) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) + +public: + explicit QxtGlobalShortcut(QObject* parent = 0); + explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0); + virtual ~QxtGlobalShortcut(); + + QKeySequence shortcut() const; + bool setShortcut(const QKeySequence& shortcut); + + bool isEnabled() const; + +public Q_SLOTS: + void setEnabled(bool enabled = true); + void setDisabled(bool disabled = true); + +Q_SIGNALS: + void activated(); +}; + +#endif // QXTGLOBALSHORTCUT_H diff --git a/3rdparty/qxt/qxtglobalshortcut_mac.cpp b/3rdparty/qxt/qxtglobalshortcut_mac.cpp new file mode 100644 index 000000000..0bcea7f36 --- /dev/null +++ b/3rdparty/qxt/qxtglobalshortcut_mac.cpp @@ -0,0 +1,207 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtGui module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ +#include +#include "qxtglobalshortcut_p.h" +#include +#include +#include +#include + +typedef QPair Identifier; +static QMap keyRefs; +static QHash keyIDs; +static quint32 hotKeySerial = 0; +static bool qxt_mac_handler_installed = false; + +OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data) +{ + // pass event to the app event filter + Q_UNUSED(data); + qApp->macEventFilter(nextHandler, event); + return noErr; +} + +bool QxtGlobalShortcutPrivate::eventFilter(void* message) +//bool QxtGlobalShortcutPrivate::macEventFilter(EventHandlerCallRef caller, EventRef event) +{ + EventRef event = (EventRef) message; + if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed) + { + EventHotKeyID keyID; + GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID); + Identifier id = keyIDs.key(keyID.id); + activateShortcut(id.second, id.first); + } + return false; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= shiftKeyBit; + if (modifiers & Qt::ControlModifier) + native |= cmdKey; + if (modifiers & Qt::AltModifier) + native |= optionKey; + if (modifiers & Qt::MetaModifier) + native |= controlKey; + if (modifiers & Qt::KeypadModifier) + native |= kEventKeyModifierNumLockMask; + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + UTF16Char ch; + // Constants found in NSEvent.h from AppKit.framework + if (key == Qt::Key_Up) ch = 0xF700; + else if (key == Qt::Key_Down) ch = 0xF701; + else if (key == Qt::Key_Left) ch = 0xF702; + else if (key == Qt::Key_Right) ch = 0xF703; + else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) + ch = key - Qt::Key_F1 + 0xF704; + else if (key == Qt::Key_Insert) ch = 0xF727; + else if (key == Qt::Key_Delete) ch = 0xF728; + else if (key == Qt::Key_Home) ch = 0xF729; + else if (key == Qt::Key_End) ch = 0xF72B; + else if (key == Qt::Key_PageUp) ch = 0xF72C; + else if (key == Qt::Key_PageDown) ch = 0xF72D; + else if (key == Qt::Key_Print) ch = 0xF72E; + else if (key == Qt::Key_ScrollLock) ch = 0xF72F; + else if (key == Qt::Key_Pause) ch = 0xF730; + else if (key == Qt::Key_SysReq) ch = 0xF731; + else if (key == Qt::Key_Stop) ch = 0xF734; + else if (key == Qt::Key_Menu) ch = 0xF735; + else if (key == Qt::Key_Select) ch = 0xF741; + else if (key == Qt::Key_Execute) ch = 0xF742; + else if (key == Qt::Key_Help) ch = 0xF746; + else if (key == Qt::Key_Mode_switch) ch = 0xF747; + else if (key == Qt::Key_Escape) ch = 27; + else if (key == Qt::Key_Return) ch = 13; + else if (key == Qt::Key_Enter) ch = 3; + else if (key == Qt::Key_Tab) ch = 9; + else ch = key; + + KeyboardLayoutRef layout; + KeyboardLayoutKind layoutKind; + KLGetCurrentKeyboardLayout(&layout); + KLGetKeyboardLayoutProperty(layout, kKLKind, const_cast(reinterpret_cast(&layoutKind))); + + if (layoutKind == kKLKCHRKind) + { // no Unicode available + if (ch > 255) return 0; + + char* data; + KLGetKeyboardLayoutProperty(layout, kKLKCHRData, const_cast(reinterpret_cast(&data))); + int ct = *reinterpret_cast(data + 258); + for (int i = 0; i < ct; i++) + { + char* keyTable = data + 260 + 128 * i; + for (int j = 0; j < 128; j++) + { + if (keyTable[j] == ch) return j; + } + } + + return 0; + } + + char* data; + KLGetKeyboardLayoutProperty(layout, kKLuchrData, const_cast(reinterpret_cast(&data))); + UCKeyboardLayout* header = reinterpret_cast(data); + UCKeyboardTypeHeader* table = header->keyboardTypeList; + + for (quint32 i=0; i < header->keyboardTypeCount; i++) + { + UCKeyStateRecordsIndex* stateRec = 0; + if (table[i].keyStateRecordsIndexOffset != 0) + { + stateRec = reinterpret_cast(data + table[i].keyStateRecordsIndexOffset); + if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0; + } + + UCKeyToCharTableIndex* charTable = reinterpret_cast(data + table[i].keyToCharTableIndexOffset); + if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue; + + for (quint32 j=0; j < charTable->keyToCharTableCount; j++) + { + UCKeyOutput* keyToChar = reinterpret_cast(data + charTable->keyToCharTableOffsets[j]); + for (quint32 k=0; k < charTable->keyToCharTableSize; k++) + { + if (keyToChar[k] & kUCKeyOutputTestForIndexMask) + { + long idx = keyToChar[k] & kUCKeyOutputGetIndexMask; + if (stateRec && idx < stateRec->keyStateRecordCount) + { + UCKeyStateRecord* rec = reinterpret_cast(data + stateRec->keyStateRecordOffsets[idx]); + if (rec->stateZeroCharData == ch) return k; + } + } + else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE) + { + if (keyToChar[k] == ch) return k; + } + } // for k + } // for j + } // for i + + return 0; +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + if (!qxt_mac_handler_installed) + { + EventTypeSpec t; + t.eventClass = kEventClassKeyboard; + t.eventKind = kEventHotKeyPressed; + InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL); + } + + EventHotKeyID keyID; + keyID.signature = 'cute'; + keyID.id = ++hotKeySerial; + + EventHotKeyRef ref = 0; + bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref); + if (rv) + { + keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id); + keyRefs.insert(keyID.id, ref); + } + qDebug() << ref; + return rv; +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + Identifier id(nativeMods, nativeKey); + if (!keyIDs.contains(id)) return false; + + EventHotKeyRef ref = keyRefs.take(keyIDs[id]); + keyIDs.remove(id); + return !UnregisterEventHotKey(ref); +} diff --git a/3rdparty/qxt/qxtglobalshortcut_p.h b/3rdparty/qxt/qxtglobalshortcut_p.h new file mode 100644 index 000000000..4570396fe --- /dev/null +++ b/3rdparty/qxt/qxtglobalshortcut_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtGui module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ +#ifndef QXTGLOBALSHORTCUT_P_H +#define QXTGLOBALSHORTCUT_P_H + +#include "qxtglobalshortcut.h" +#include +#include +#include + +class QxtGlobalShortcutPrivate : public QxtPrivate +{ +public: + QXT_DECLARE_PUBLIC(QxtGlobalShortcut) + QxtGlobalShortcutPrivate(); + ~QxtGlobalShortcutPrivate(); + + bool enabled; + Qt::Key key; + Qt::KeyboardModifiers mods; + + bool setShortcut(const QKeySequence& shortcut); + bool unsetShortcut(); + + static bool error; + static int ref; + static QAbstractEventDispatcher::EventFilter prevEventFilter; + static bool eventFilter(void* message); + +private: + static quint32 nativeKeycode(Qt::Key keycode); + static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers); + + static bool registerShortcut(quint32 nativeKey, quint32 nativeMods); + static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods); + static void activateShortcut(quint32 nativeKey, quint32 nativeMods); + + static QHash, QxtGlobalShortcut*> shortcuts; +}; + +#endif // QXTGLOBALSHORTCUT_P_H diff --git a/3rdparty/qxt/qxtglobalshortcut_win.cpp b/3rdparty/qxt/qxtglobalshortcut_win.cpp new file mode 100644 index 000000000..d81f1089d --- /dev/null +++ b/3rdparty/qxt/qxtglobalshortcut_win.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtGui module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ +#include "qxtglobalshortcut_p.h" +#include + +bool QxtGlobalShortcutPrivate::eventFilter(void* message) +{ + MSG* msg = static_cast(message); + if (msg->message == WM_HOTKEY) + { + const quint32 keycode = HIWORD(msg->lParam); + const quint32 modifiers = LOWORD(msg->lParam); + activateShortcut(keycode, modifiers); + } + return false; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= MOD_SHIFT; + if (modifiers & Qt::ControlModifier) + native |= MOD_CONTROL; + if (modifiers & Qt::AltModifier) + native |= MOD_ALT; + if (modifiers & Qt::MetaModifier) + native |= MOD_WIN; + // TODO: resolve these? + //if (modifiers & Qt::KeypadModifier) + //if (modifiers & Qt::GroupSwitchModifier) + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + switch (key) + { + case Qt::Key_Escape: + return VK_ESCAPE; + case Qt::Key_Tab: + case Qt::Key_Backtab: + return VK_TAB; + case Qt::Key_Backspace: + return VK_BACK; + case Qt::Key_Return: + case Qt::Key_Enter: + return VK_RETURN; + case Qt::Key_Insert: + return VK_INSERT; + case Qt::Key_Delete: + return VK_DELETE; + case Qt::Key_Pause: + return VK_PAUSE; + case Qt::Key_Print: + return VK_PRINT; + case Qt::Key_Clear: + return VK_CLEAR; + case Qt::Key_Home: + return VK_HOME; + case Qt::Key_End: + return VK_END; + case Qt::Key_Left: + return VK_LEFT; + case Qt::Key_Up: + return VK_UP; + case Qt::Key_Right: + return VK_RIGHT; + case Qt::Key_Down: + return VK_DOWN; + case Qt::Key_PageUp: + return VK_PRIOR; + case Qt::Key_PageDown: + return VK_NEXT; + case Qt::Key_F1: + return VK_F1; + case Qt::Key_F2: + return VK_F2; + case Qt::Key_F3: + return VK_F3; + case Qt::Key_F4: + return VK_F4; + case Qt::Key_F5: + return VK_F5; + case Qt::Key_F6: + return VK_F6; + case Qt::Key_F7: + return VK_F7; + case Qt::Key_F8: + return VK_F8; + case Qt::Key_F9: + return VK_F9; + case Qt::Key_F10: + return VK_F10; + case Qt::Key_F11: + return VK_F11; + case Qt::Key_F12: + return VK_F12; + case Qt::Key_F13: + return VK_F13; + case Qt::Key_F14: + return VK_F14; + case Qt::Key_F15: + return VK_F15; + case Qt::Key_F16: + return VK_F16; + case Qt::Key_F17: + return VK_F17; + case Qt::Key_F18: + return VK_F18; + case Qt::Key_F19: + return VK_F19; + case Qt::Key_F20: + return VK_F20; + case Qt::Key_F21: + return VK_F21; + case Qt::Key_F22: + return VK_F22; + case Qt::Key_F23: + return VK_F23; + case Qt::Key_F24: + return VK_F24; + case Qt::Key_Space: + return VK_SPACE; + case Qt::Key_Asterisk: + return VK_MULTIPLY; + case Qt::Key_Plus: + return VK_ADD; + case Qt::Key_Comma: + return VK_SEPARATOR; + case Qt::Key_Minus: + return VK_SUBTRACT; + case Qt::Key_Slash: + return VK_DIVIDE; + + case Qt::Key_MediaNext: + return VK_MEDIA_NEXT_TRACK; + case Qt::Key_MediaPrevious: + return VK_MEDIA_PREV_TRACK; + case Qt::Key_MediaStop: + return VK_MEDIA_STOP; + case Qt::Key_MediaPlay: + return VK_MEDIA_PLAY_PAUSE; + case Qt::Key_VolumeDown: + return VK_VOLUME_DOWN; + case Qt::Key_VolumeUp: + return VK_VOLUME_UP; + case Qt::Key_VolumeMute: + return VK_VOLUME_MUTE; + + // numbers + case Qt::Key_0: + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_8: + case Qt::Key_9: + return key; + + // letters + case Qt::Key_A: + case Qt::Key_B: + case Qt::Key_C: + case Qt::Key_D: + case Qt::Key_E: + case Qt::Key_F: + case Qt::Key_G: + case Qt::Key_H: + case Qt::Key_I: + case Qt::Key_J: + case Qt::Key_K: + case Qt::Key_L: + case Qt::Key_M: + case Qt::Key_N: + case Qt::Key_O: + case Qt::Key_P: + case Qt::Key_Q: + case Qt::Key_R: + case Qt::Key_S: + case Qt::Key_T: + case Qt::Key_U: + case Qt::Key_V: + case Qt::Key_W: + case Qt::Key_X: + case Qt::Key_Y: + case Qt::Key_Z: + return key; + + default: + return 0; + } +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey); +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + return UnregisterHotKey(0, nativeMods ^ nativeKey); +} diff --git a/3rdparty/qxt/qxtglobalshortcut_x11.cpp b/3rdparty/qxt/qxtglobalshortcut_x11.cpp new file mode 100644 index 000000000..c22894dc1 --- /dev/null +++ b/3rdparty/qxt/qxtglobalshortcut_x11.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtGui module of the Qxt library. + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of the Common Public License, version 1.0, as published + ** by IBM, and/or under the terms of the GNU Lesser General Public License, + ** version 2.1, as published by the Free Software Foundation. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL and the LGPL along with this + ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files + ** included with the source distribution for more information. + ** If you did not receive a copy of the licenses, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ +#include "qxtglobalshortcut_p.h" +#include +#include + +#include "keymapper_x11.h" + +static int (*original_x_errhandler)(Display* display, XErrorEvent* event); + +static int qxt_x_errhandler(Display* display, XErrorEvent *event) +{ + Q_UNUSED(display); + switch (event->error_code) + { + case BadAccess: + case BadValue: + case BadWindow: + if (event->request_code == 33 /* X_GrabKey */ || + event->request_code == 34 /* X_UngrabKey */) + { + QxtGlobalShortcutPrivate::error = true; + //TODO: + //char errstr[256]; + //XGetErrorText(dpy, err->error_code, errstr, 256); + } + default: + return 0; + } +} + +bool QxtGlobalShortcutPrivate::eventFilter(void* message) +{ + XEvent* event = static_cast(message); + if (event->type == KeyPress) + { + XKeyEvent* key = (XKeyEvent*) event; + activateShortcut(key->keycode, + // Mod1Mask == Alt, Mod4Mask == Meta + key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)); + } + return false; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= ShiftMask; + if (modifiers & Qt::ControlModifier) + native |= ControlMask; + if (modifiers & Qt::AltModifier) + native |= Mod1Mask; + if (modifiers & Qt::MetaModifier) + native |= Mod4Mask; + // TODO: resolve these? + //if (modifiers & Qt::KeypadModifier) + //if (modifiers & Qt::GroupSwitchModifier) + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + // (davidsansome) Try the table from QKeyMapper first - this seems to be + // the only way to get Keysyms for the media keys. + unsigned int keysym = 0; + int i = 0; + while (KeyTbl[i]) { + if (KeyTbl[i+1] == static_cast(key)) { + keysym = KeyTbl[i]; + break; + } + i += 2; + } + + // If that didn't work then fall back on XStringToKeysym + if (!keysym) { + keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data()); + } + + Display* display = QX11Info::display(); + return XKeysymToKeycode(display, keysym); +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + Display* display = QX11Info::display(); + Window window = QX11Info::appRootWindow(); + Bool owner = True; + int pointer = GrabModeAsync; + int keyboard = GrabModeAsync; + error = false; + original_x_errhandler = XSetErrorHandler(qxt_x_errhandler); + XGrabKey(display, nativeKey, nativeMods, window, owner, pointer, keyboard); + XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner, pointer, keyboard); // allow numlock + XSync(display, False); + XSetErrorHandler(original_x_errhandler); + return !error; +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + Display* display = QX11Info::display(); + Window window = QX11Info::appRootWindow(); + error = false; + original_x_errhandler = XSetErrorHandler(qxt_x_errhandler); + XUngrabKey(display, nativeKey, nativeMods, window); + XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); // allow numlock + XSync(display, False); + XSetErrorHandler(original_x_errhandler); + return !error; +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d9bdffa6..03f42c578 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,9 +25,9 @@ option(ENABLE_TAGLIB "Enable TagLib library(required for tag editing, replaygain option(ENABLE_TAGLIB_EXTRAS "Enable TagLib-Extras library(used by tag editing, replaygain calculation, device support, etc)" ON) option(ENABLE_HTTP_STREAM_PLAYBACK "Enable playback of MPD HTTP streams(Phonon required for Qt4, QtMultimedia for Qt5)" OFF) if (WIN32) - option(ENABLE_HTTPS_SUPPORT "Enable HTTPS URLs for LAst.fm, Wikipedia, SoundCloud, etc. (Requires a Qt built with SSL support)" OFF) + option(ENABLE_HTTPS_SUPPORT "Enable HTTPS URLs for Last.fm, Wikipedia, SoundCloud, etc. (Requires a Qt built with SSL support)" OFF) else (WIN32) - option(ENABLE_HTTPS_SUPPORT "Enable HTTPS URLs for LAst.fm, Wikipedia, SoundCloud, etc." ON) + option(ENABLE_HTTPS_SUPPORT "Enable HTTPS URLs for Last.fm, Wikipedia, SoundCloud, etc." ON) endif (WIN32) option(ENABLE_KDE "Enable KDE libraries" ON) option(ENABLE_QT5 "Build against Qt5" OFF) @@ -53,7 +53,7 @@ endif (ENABLE_UDISKS2) set(CANTATA_SRCS gui/application.cpp gui/main.cpp gui/initialsettingswizard.cpp gui/mainwindow.cpp gui/preferencesdialog.cpp gui/settings.cpp gui/covers.cpp gui/filesettings.cpp gui/interfacesettings.cpp gui/playbacksettings.cpp gui/serversettings.cpp gui/librarypage.cpp gui/albumspage.cpp gui/folderpage.cpp gui/playlistspage.cpp gui/trayitem.cpp - gui/cachesettings.cpp gui/coverdialog.cpp gui/stdactions.cpp + gui/cachesettings.cpp gui/coverdialog.cpp gui/stdactions.cpp gui/mediakeys.cpp streams/streamspage.cpp streams/streamdialog.cpp streams/streamfetcher.cpp streams/digitallyimportedsettings.cpp streams/streamssettings.cpp streams/tar.cpp models/musiclibraryitemroot.cpp models/musiclibraryitemartist.cpp models/musiclibraryitemalbum.cpp models/musiclibrarymodel.cpp @@ -81,7 +81,7 @@ set(CANTATA_SRCS gui/application.cpp gui/main.cpp gui/initialsettingswizard.cpp set(CANTATA_MOC_HDRS gui/initialsettingswizard.h gui/mainwindow.h gui/settings.h gui/covers.h gui/folderpage.h gui/librarypage.h gui/albumspage.h gui/playlistspage.h gui/playbacksettings.h gui/serversettings.h gui/preferencesdialog.h gui/filesettings.h - gui/interfacesettings.h gui/cachesettings.h gui/trayitem.h gui/coverdialog.h + gui/interfacesettings.h gui/cachesettings.h gui/trayitem.h gui/coverdialog.h gui/multimediakeysinterface.h streams/streamspage.h streams/streamdialog.h streams/streamfetcher.h streams/digitallyimportedsettings.h streams/streamssettings.h models/musiclibrarymodel.h models/musiclibraryproxymodel.h models/playlistsmodel.h models/playlistsproxymodel.h models/playqueuemodel.h models/playqueueproxymodel.h models/dirviewmodel.h models/dirviewproxymodel.h models/albumsmodel.h models/streamsmodel.h @@ -429,6 +429,12 @@ else (ENABLE_KDE_SUPPORT) QT4_WRAP_CPP(CANTATA_MOC_SRCS ${CANTATA_MOC_HDRS}) endif (ENABLE_QT5) + if (NOT APPLE AND NOT ENABLE_QT5) + add_subdirectory(3rdparty/qxt) + include_directories(${CMAKE_SOURCE_DIR}/3rdparty/qxt) + set(CANTATA_SRCS ${CANTATA_SRCS} gui/qxtmediakeys.cpp) + endif (NOT APPLE AND NOT ENABLE_QT5) + if (WIN32) set(CMAKE_BUILD_TYPE "Release") ADD_EXECUTABLE(cantata WIN32 ${CANTATA_SRCS} ${CANTATA_MOC_SRCS} ${CANTATA_RC_SRCS} ${CANTATA_UI_HDRS} ${CANTATA_PO}) @@ -459,6 +465,9 @@ else (ENABLE_KDE_SUPPORT) add_subdirectory(3rdparty/qtsingleapplication) target_link_libraries(cantata qtsingleapplication) endif (WIN32) + if (NOT APPLE AND NOT ENABLE_QT5) + target_link_libraries(cantata qxt) + endif (NOT APPLE AND NOT ENABLE_QT5) endif (ENABLE_KDE_SUPPORT) if (ENABLE_HTTP_STREAM_PLAYBACK AND NOT ENABLE_QT5) diff --git a/ChangeLog b/ChangeLog index c9f8d42c9..d079b260c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -54,6 +54,9 @@ 26. Dont build GNOME media-keys support into KDE builds, as these use KDE's global keyboard shortcuts. 27. With KDE builds, default to using media-keys as global shortcuts. +28. Optionally support Qxt global shortcuts for Qt-only (Qt4) Linux, and + Windows, builds. +29. Move media-keys setting into shortcuts page. 1.1.3 ----- diff --git a/README b/README index 408bb9e91..df14ea409 100644 --- a/README +++ b/README @@ -395,11 +395,15 @@ the respective category. ================== Cantata may be controlled via the media keys on some keyboards. To enable this, -the KDE version can be configured to use KDE's global shortcuts. The Qt only -builds (under Linux) can use the GNOME settings daemon's MediaKeys interface. -This interface is normally started automatically under GNOME/Unity - and you -will also need to enable the setting in Cantata's configuration dialog (as of -v1.1 this option is enabled by default) +the KDE version can be configured to use KDE's global shortcuts. + +Linux Qt4 and Windows builds, as of 1.2, now also support basic media-keys +shortcuts. + +Linux Qt4 and Qt5 builds can also use the GNOME settings daemon's MediaKeys +interface. This interface is normally started automatically undet GNOME/Unity +- and you will also need to enable the setting in the shortcuts page of +Cantata's configuration dialog (as of v1.1 this option is enabled by default) If your system does not have this daemon, you could possibly use https://code.google.com/p/mediakeys-daemon/ which is a python re-implementation diff --git a/dbus/gnomemediakeys.cpp b/dbus/gnomemediakeys.cpp index 45b128c8d..d4be1bb5c 100644 --- a/dbus/gnomemediakeys.cpp +++ b/dbus/gnomemediakeys.cpp @@ -22,7 +22,6 @@ */ #include "gnomemediakeys.h" -#include "mainwindow.h" #include "settingsdaemoninterface.h" #include "mediakeysinterface.h" #include @@ -36,31 +35,21 @@ static const char * constService = "org.gnome.SettingsDaemon"; static const char * constDaemonPath = "/org/gnome/SettingsDaemon"; static const char * constMediaKeysPath = "/org/gnome/SettingsDaemon/MediaKeys"; -GnomeMediaKeys::GnomeMediaKeys(MainWindow *parent) - : QObject(parent) - , mw(parent) +GnomeMediaKeys::GnomeMediaKeys(QObject *p) + : MultiMediaKeysInterface(p) , daemon(0) , mk(0) , watcher(0) { } -static bool runningUnderKde() +void GnomeMediaKeys::activate(bool a) { - const char *env=qgetenv("KDE_FULL_SESSION"); - if (env && 0==strcmp(env, "true")) { - return true; - } - return QLatin1String("KDE")==QString(qgetenv("XDG_CURRENT_DESKTOP")); -} - -void GnomeMediaKeys::setEnabled(bool en) -{ - if (en && !mk) { + if (a && !mk) { if (daemonIsRunning()) { grabKeys(); } - } else if (!en && mk) { + } else if (!a && mk) { releaseKeys(); disconnectDaemon(); if (watcher) { @@ -73,7 +62,7 @@ void GnomeMediaKeys::setEnabled(bool en) bool GnomeMediaKeys::daemonIsRunning() { // Check if the service is available - if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(constService) && !runningUnderKde()) { + if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(constService)) { //...not already started, so attempt to start! QDBusConnection::sessionBus().interface()->startService(constService); if (!daemon) { @@ -153,13 +142,13 @@ void GnomeMediaKeys::keyPressed(const QString &app, const QString &key) return; } if (QLatin1String("Play")==key) { - mw->playPauseTrack(); + emit playPause(); } else if (QLatin1String("Stop")==key) { - mw->stopPlayback(); + emit stop(); } else if (QLatin1String("Next")==key) { - mw->nextTrack(); + emit next(); } else if (QLatin1String("Previous")==key) { - mw->prevTrack(); + emit previous(); } } diff --git a/dbus/gnomemediakeys.h b/dbus/gnomemediakeys.h index cb635c427..b6314660a 100644 --- a/dbus/gnomemediakeys.h +++ b/dbus/gnomemediakeys.h @@ -24,22 +24,21 @@ #ifndef GNOME_MEDIA_KEYS_H #define GNOME_MEDIA_KEYS_H -#include +#include "multimediakeysinterface.h" class OrgGnomeSettingsDaemonInterface; class OrgGnomeSettingsDaemonMediaKeysInterface; class QDBusPendingCallWatcher; -class MainWindow; class QDBusServiceWatcher; -class GnomeMediaKeys : public QObject +class GnomeMediaKeys : public MultiMediaKeysInterface { Q_OBJECT public: - GnomeMediaKeys(MainWindow *parent); + GnomeMediaKeys(QObject *p); - void setEnabled(bool en); + void activate(bool a); private: bool daemonIsRunning(); @@ -54,7 +53,6 @@ private Q_SLOTS: void pluginActivated(const QString &name); private: - MainWindow *mw; OrgGnomeSettingsDaemonInterface *daemon; OrgGnomeSettingsDaemonMediaKeysInterface *mk; QDBusServiceWatcher *watcher; diff --git a/dbus/mpris.cpp b/dbus/mpris.cpp index 87ad699f0..3da6e7895 100644 --- a/dbus/mpris.cpp +++ b/dbus/mpris.cpp @@ -26,6 +26,7 @@ #include "playeradaptor.h" #include "rootadaptor.h" #include "config.h" +#include "mainwindow.h" #ifdef ENABLE_KDE_SUPPORT #include #endif diff --git a/dbus/mpris.h b/dbus/mpris.h index ac24a2e1f..ddbd6b793 100644 --- a/dbus/mpris.h +++ b/dbus/mpris.h @@ -30,9 +30,10 @@ #include #include "song.h" #include "mpdstatus.h" -#include "mainwindow.h" +#include "stdactions.h" class QDBusObjectPath; +class MainWindow; class Mpris : public QObject { @@ -69,23 +70,23 @@ public: virtual ~Mpris() { } // org.mpris.MediaPlayer2.Player - void Next() { mw->nextTrack(); } - void Previous() { mw->prevTrack(); } + void Next() { StdActions::self()->nextTrackAction->trigger(); } + void Previous() { StdActions::self()->prevTrackAction->trigger(); } void Pause() { if (MPDState_Playing==MPDStatus::self()->state()) { - mw->playPauseTrack(); + StdActions::self()->playPauseTrackAction->trigger(); } } - void PlayPause() { mw->playPauseTrack(); } - void Stop() { mw->stopPlayback(); } - void StopAfterCurrent() { mw->stopAfterCurrentTrack(); } + void PlayPause() { StdActions::self()->playPauseTrackAction->trigger(); } + void Stop() { StdActions::self()->stopPlaybackAction->trigger(); } + void StopAfterCurrent() { StdActions::self()->stopAfterTrackAction->trigger(); } void Play() { MPDStatus * const status = MPDStatus::self(); if (status->playlistLength() && MPDState_Playing!=status->state()) { - mw->playPauseTrack(); + StdActions::self()->playPauseTrackAction->trigger(); } } diff --git a/gui/interfacesettings.cpp b/gui/interfacesettings.cpp index ecfb9e106..b086d7946 100644 --- a/gui/interfacesettings.cpp +++ b/gui/interfacesettings.cpp @@ -28,12 +28,6 @@ #include "musiclibraryitemalbum.h" #include "onoffbutton.h" #include -#include - -#define REMOVE(w) \ - w->setVisible(false); \ - w->deleteLater(); \ - w=0; static void addImageSizes(QComboBox *box) { @@ -101,10 +95,6 @@ InterfaceSettings::InterfaceSettings(QWidget *p) showDeleteAction->setVisible(false); showDeleteActionLabel->setVisible(false); #endif - #if defined Q_OS_WIN || defined ENABLE_KDE_SUPPORT - REMOVE(gnomeMediaKeys) - REMOVE(gnomeMediaKeysLabel) - #endif connect(systemTrayCheckBox, SIGNAL(toggled(bool)), minimiseOnClose, SLOT(setEnabled(bool))); connect(systemTrayCheckBox, SIGNAL(toggled(bool)), minimiseOnCloseLabel, SLOT(setEnabled(bool))); connect(forceSingleClick, SIGNAL(toggled(bool)), SLOT(forceSingleClickChanged())); @@ -146,9 +136,6 @@ void InterfaceSettings::load() minimiseOnClose->setChecked(Settings::self()->minimiseOnClose()); minimiseOnClose->setEnabled(systemTrayCheckBox->isChecked()); minimiseOnCloseLabel->setEnabled(systemTrayCheckBox->isChecked()); - #if !defined Q_OS_WIN && !defined ENABLE_KDE_SUPPORT - gnomeMediaKeys->setChecked(Settings::self()->gnomeMediaKeys()); - #endif } void InterfaceSettings::save() @@ -181,9 +168,6 @@ void InterfaceSettings::save() Settings::self()->saveUseSystemTray(systemTrayCheckBox->isChecked()); Settings::self()->saveShowPopups(systemTrayPopup->isChecked()); Settings::self()->saveMinimiseOnClose(minimiseOnClose->isChecked()); - #if !defined Q_OS_WIN && !defined ENABLE_KDE_SUPPORT - Settings::self()->saveGnomeMediaKeys(gnomeMediaKeys->isChecked()); - #endif } void InterfaceSettings::libraryViewChanged() diff --git a/gui/interfacesettings.ui b/gui/interfacesettings.ui index 003ad4744..f7e517198 100644 --- a/gui/interfacesettings.ui +++ b/gui/interfacesettings.ui @@ -455,19 +455,6 @@ within the folder of the current track, or within its parent folder. If no image - - - - Support media keys under GNOME/Unity: - - - gnomeMediaKeys - - - - - - @@ -642,7 +629,6 @@ within the folder of the current track, or within its parent folder. If no image systemTrayCheckBox minimiseOnClose systemTrayPopup - gnomeMediaKeys groupSingle groupMultiple showDeleteAction diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 9ea2bda6a..fd19f0cb3 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -51,6 +51,7 @@ #else #include #include "networkproxyfactory.h" +#include "mediakeys.h" #endif #include "localize.h" #include "qtplural.h" @@ -108,7 +109,6 @@ #if !defined Q_OS_WIN && !defined Q_OS_MAC #include "mpris.h" #include "cantataadaptor.h" -#include "gnomemediakeys.h" #include "mountpoints.h" #include "gtkproxystyle.h" #include "powermanagement.h" @@ -150,11 +150,11 @@ bool VolumeSliderEventHandler::eventFilter(QObject *obj, QEvent *event) int numSteps = numDegrees / 15; if (numSteps > 0) { for (int i = 0; i < numSteps; ++i) { - window->increaseVolumeAction->trigger(); + StdActions::self()->increaseVolumeAction->trigger(); } } else { for (int i = 0; i > numSteps; --i) { - window->decreaseVolumeAction->trigger(); + StdActions::self()->decreaseVolumeAction->trigger(); } } return true; @@ -202,9 +202,6 @@ MainWindow::MainWindow(QWidget *parent) , autoScrollPlayQueue(true) #if !defined Q_OS_WIN && !defined Q_OS_MAC , mpris(0) - #ifndef ENABLE_KDE_SUPPORT - , gnomeMediaKeys(0) - #endif #endif , statusTimer(0) , playQueueSearchTimer(0) @@ -287,14 +284,7 @@ MainWindow::MainWindow(QWidget *parent) connectAction = ActionCollection::get()->createAction("connect", i18n("Connect"), Icons::self()->connectIcon); connectionsAction = ActionCollection::get()->createAction("connections", i18n("Collection"), "network-server"); outputsAction = ActionCollection::get()->createAction("outputs", i18n("Outputs"), Icons::self()->speakerIcon); - prevTrackAction = ActionCollection::get()->createAction("prevtrack", i18n("Previous Track"), Icons::self()->toolbarPrevIcon); - nextTrackAction = ActionCollection::get()->createAction("nexttrack", i18n("Next Track"), Icons::self()->toolbarNextIcon); - playPauseTrackAction = ActionCollection::get()->createAction("playpausetrack", i18n("Play/Pause"), Icons::self()->toolbarPlayIcon); - stopPlaybackAction = ActionCollection::get()->createAction("stopplayback", i18n("Stop"), Icons::self()->toolbarStopIcon); - stopAfterCurrentTrackAction = ActionCollection::get()->createAction("stopaftercurrenttrack", i18n("Stop After Current Track"), Icons::self()->toolbarStopIcon); stopAfterTrackAction = ActionCollection::get()->createAction("stopaftertrack", i18n("Stop After Track"), Icons::self()->toolbarStopIcon); - increaseVolumeAction = ActionCollection::get()->createAction("increasevolume", i18n("Increase Volume")); - decreaseVolumeAction = ActionCollection::get()->createAction("decreasevolume", i18n("Decrease Volume")); muteAction = ActionCollection::get()->createAction("mute", i18n("Mute")); addPlayQueueToStoredPlaylistAction = ActionCollection::get()->createAction("addpqtostoredplaylist", i18n("Add To Stored Playlist"), Icons::self()->playlistIcon); removeFromPlayQueueAction = ActionCollection::get()->createAction("removefromplaylist", i18n("Remove From Play Queue"), "list-remove"); @@ -337,23 +327,23 @@ MainWindow::MainWindow(QWidget *parent) expandAllAction = ActionCollection::get()->createAction("expandall", i18n("Expand All")); collapseAllAction = ActionCollection::get()->createAction("collapseall", i18n("Collapse All")); - playPauseTrackAction->setEnabled(false); - nextTrackAction->setEnabled(false); + StdActions::self()->playPauseTrackAction->setEnabled(false); + StdActions::self()->nextTrackAction->setEnabled(false); updateNextTrack(-1); - prevTrackAction->setEnabled(false); + StdActions::self()->prevTrackAction->setEnabled(false); enableStopActions(false); - addAction(increaseVolumeAction); - addAction(decreaseVolumeAction); + addAction(StdActions::self()->increaseVolumeAction); + addAction(StdActions::self()->decreaseVolumeAction); addAction(muteAction); #if defined ENABLE_KDE_SUPPORT - prevTrackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaPrevious)); - nextTrackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaNext)); - playPauseTrackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaPlay)); - stopPlaybackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaStop)); - stopAfterCurrentTrackAction->setGlobalShortcut(KShortcut()); - increaseVolumeAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeUp)); - decreaseVolumeAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeDown)); + StdActions::self()->prevTrackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaPrevious)); + StdActions::self()->nextTrackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaNext)); + StdActions::self()->playPauseTrackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaPlay)); + StdActions::self()->stopPlaybackAction->setGlobalShortcut(KShortcut(Qt::Key_MediaStop)); + StdActions::self()->stopAfterCurrentTrackAction->setGlobalShortcut(KShortcut()); + StdActions::self()->increaseVolumeAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeUp)); + StdActions::self()->decreaseVolumeAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeDown)); muteAction->setGlobalShortcut(KShortcut(Qt::Key_VolumeMute)); #endif @@ -390,14 +380,14 @@ MainWindow::MainWindow(QWidget *parent) menuButton->setMenu(mainMenu); volumeButton->setIcon(Icons::self()->toolbarVolumeHighIcon); - playPauseTrackButton->setDefaultAction(playPauseTrackAction); - stopTrackButton->setDefaultAction(stopPlaybackAction); - nextTrackButton->setDefaultAction(nextTrackAction); - prevTrackButton->setDefaultAction(prevTrackAction); + playPauseTrackButton->setDefaultAction(StdActions::self()->playPauseTrackAction); + stopTrackButton->setDefaultAction(StdActions::self()->stopPlaybackAction); + nextTrackButton->setDefaultAction(StdActions::self()->nextTrackAction); + prevTrackButton->setDefaultAction(StdActions::self()->prevTrackAction); QMenu *stopMenu=new QMenu(this); - stopMenu->addAction(stopPlaybackAction); - stopMenu->addAction(stopAfterCurrentTrackAction); + stopMenu->addAction(StdActions::self()->stopPlaybackAction); + stopMenu->addAction(StdActions::self()->stopAfterCurrentTrackAction); stopTrackButton->setMenu(stopMenu); stopTrackButton->setPopupMode(QToolButton::DelayedPopup); @@ -754,16 +744,16 @@ MainWindow::MainWindow(QWidget *parent) connect(StdActions::self()->refreshAction, SIGNAL(triggered(bool)), this, SLOT(refresh())); connect(StdActions::self()->refreshAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(update())); connect(connectAction, SIGNAL(triggered(bool)), this, SLOT(connectToMpd())); - connect(prevTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToPrevious())); - connect(nextTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToNext())); - connect(playPauseTrackAction, SIGNAL(triggered(bool)), this, SLOT(playPauseTrack())); - connect(stopPlaybackAction, SIGNAL(triggered(bool)), this, SLOT(stopPlayback())); - connect(stopAfterCurrentTrackAction, SIGNAL(triggered(bool)), this, SLOT(stopAfterCurrentTrack())); + connect(StdActions::self()->prevTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToPrevious())); + connect(StdActions::self()->nextTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToNext())); + connect(StdActions::self()->playPauseTrackAction, SIGNAL(triggered(bool)), this, SLOT(playPauseTrack())); + connect(StdActions::self()->stopPlaybackAction, SIGNAL(triggered(bool)), this, SLOT(stopPlayback())); + connect(StdActions::self()->stopAfterCurrentTrackAction, SIGNAL(triggered(bool)), this, SLOT(stopAfterCurrentTrack())); connect(stopAfterTrackAction, SIGNAL(triggered(bool)), this, SLOT(stopAfterTrack())); connect(volumeControl, SIGNAL(valueChanged(int)), MPDConnection::self(), SLOT(setVolume(int))); connect(this, SIGNAL(setVolume(int)), MPDConnection::self(), SLOT(setVolume(int))); - connect(increaseVolumeAction, SIGNAL(triggered(bool)), volumeControl, SLOT(increaseVolume())); - connect(decreaseVolumeAction, SIGNAL(triggered(bool)), volumeControl, SLOT(decreaseVolume())); + connect(StdActions::self()->increaseVolumeAction, SIGNAL(triggered(bool)), volumeControl, SLOT(increaseVolume())); + connect(StdActions::self()->decreaseVolumeAction, SIGNAL(triggered(bool)), volumeControl, SLOT(decreaseVolume())); connect(muteAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(toggleMute())); connect(positionSlider, SIGNAL(sliderReleased()), this, SLOT(setPosition())); connect(randomPlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setRandom(bool))); @@ -842,7 +832,6 @@ MainWindow::MainWindow(QWidget *parent) connect(MountPoints::self(), SIGNAL(updated()), SLOT(checkMpdAccessibility())); #endif // Q_OS_LINUX connect(OnlineServicesModel::self(), SIGNAL(error(const QString &)), this, SLOT(showError(const QString &))); - playQueueItemsSelected(false); playQueue->setFocus(); playQueue->initHeader(); @@ -890,6 +879,7 @@ MainWindow::MainWindow(QWidget *parent) if (Settings::self()->firstRun() && MPDConnection::self()->isConnected()) { mpdConnectionStateChanged(true); } + MediaKeys::self()->load(); } MainWindow::~MainWindow() @@ -1397,16 +1387,9 @@ void MainWindow::readSettings() updateWindowTitle(); TreeView::setForceSingleClick(Settings::self()->forceSingleClick()); #if !defined Q_OS_WIN && !defined Q_OS_MAC - #ifndef ENABLE_KDE_SUPPORT - if (!gnomeMediaKeys && Settings::self()->gnomeMediaKeys()) { - gnomeMediaKeys=new GnomeMediaKeys(this); - } - if (gnomeMediaKeys) { - gnomeMediaKeys->setEnabled(Settings::self()->gnomeMediaKeys()); - } - #endif PowerManagement::self()->setInhibitSuspend(Settings::self()->inhibitSuspend()); #endif + MediaKeys::self()->load(); context->readConfig(); } @@ -1608,8 +1591,8 @@ void MainWindow::toggleStream(bool s, const QString &url) void MainWindow::enableStopActions(bool enable) { - stopAfterCurrentTrackAction->setEnabled(enable); - stopPlaybackAction->setEnabled(enable); + StdActions::self()->stopAfterCurrentTrackAction->setEnabled(enable); + StdActions::self()->stopPlaybackAction->setEnabled(enable); } void MainWindow::stopPlayback() @@ -1618,8 +1601,8 @@ void MainWindow::stopPlayback() emit stop(); } enableStopActions(false); - nextTrackAction->setEnabled(false); - prevTrackAction->setEnabled(false); + StdActions::self()->nextTrackAction->setEnabled(false); + StdActions::self()->prevTrackAction->setEnabled(false); startVolumeFade(); } @@ -1700,16 +1683,6 @@ void MainWindow::playPauseTrack() } } -void MainWindow::nextTrack() -{ - nextTrackAction->trigger(); -} - -void MainWindow::prevTrack() -{ - prevTrackAction->trigger(); -} - void MainWindow::setPosition() { emit setSeekId(MPDStatus::self()->songId(), positionSlider->value()); @@ -1754,9 +1727,9 @@ void MainWindow::realSearchPlayQueue() void MainWindow::updatePlayQueue(const QList &songs) { - playPauseTrackAction->setEnabled(!songs.isEmpty()); - nextTrackAction->setEnabled(stopPlaybackAction->isEnabled() && songs.count()>1); - prevTrackAction->setEnabled(stopPlaybackAction->isEnabled() && songs.count()>1); + StdActions::self()->playPauseTrackAction->setEnabled(!songs.isEmpty()); + StdActions::self()->nextTrackAction->setEnabled(StdActions::self()->stopPlaybackAction->isEnabled() && songs.count()>1); + StdActions::self()->prevTrackAction->setEnabled(StdActions::self()->stopPlaybackAction->isEnabled() && songs.count()>1); StdActions::self()->savePlayQueueAction->setEnabled(!songs.isEmpty()); clearPlayQueueAction->setEnabled(!songs.isEmpty()); @@ -1992,8 +1965,8 @@ void MainWindow::updateStatus(MPDStatus * const status) volumeControl->setValue(volume); } muteAction->setEnabled(volumeButton->isEnabled()); - increaseVolumeAction->setEnabled(volumeButton->isEnabled()); - decreaseVolumeAction->setEnabled(volumeButton->isEnabled()); + StdActions::self()->increaseVolumeAction->setEnabled(volumeButton->isEnabled()); + StdActions::self()->decreaseVolumeAction->setEnabled(volumeButton->isEnabled()); volumeControl->blockSignals(false); } @@ -2019,13 +1992,13 @@ void MainWindow::updateStatus(MPDStatus * const status) httpStream->play(); } #endif - playPauseTrackAction->setIcon(Icons::self()->toolbarPauseIcon); - playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); + StdActions::self()->playPauseTrackAction->setIcon(Icons::self()->toolbarPauseIcon); + StdActions::self()->playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); //playPauseTrackButton->setChecked(false); if (StopState_Stopping!=stopState) { enableStopActions(true); - nextTrackAction->setEnabled(playQueueModel.rowCount()>1); - prevTrackAction->setEnabled(playQueueModel.rowCount()>1); + StdActions::self()->nextTrackAction->setEnabled(playQueueModel.rowCount()>1); + StdActions::self()->prevTrackAction->setEnabled(playQueueModel.rowCount()>1); } positionSlider->startTimer(); @@ -2042,12 +2015,12 @@ void MainWindow::updateStatus(MPDStatus * const status) httpStream->stop(); } #endif - playPauseTrackAction->setIcon(Icons::self()->toolbarPlayIcon); - playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); + StdActions::self()->playPauseTrackAction->setIcon(Icons::self()->toolbarPlayIcon); + StdActions::self()->playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); enableStopActions(false); - nextTrackAction->setEnabled(false); - prevTrackAction->setEnabled(false); - if (!playPauseTrackAction->isEnabled()) { + StdActions::self()->nextTrackAction->setEnabled(false); + StdActions::self()->prevTrackAction->setEnabled(false); + if (!StdActions::self()->playPauseTrackAction->isEnabled()) { trackLabel->setText(QString()); artistLabel->setText(QString()); current=Song(); @@ -2070,11 +2043,11 @@ void MainWindow::updateStatus(MPDStatus * const status) httpStream->pause(); } #endif - playPauseTrackAction->setIcon(Icons::self()->toolbarPlayIcon); - playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); + StdActions::self()->playPauseTrackAction->setIcon(Icons::self()->toolbarPlayIcon); + StdActions::self()->playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); enableStopActions(0!=playQueueModel.rowCount()); - nextTrackAction->setEnabled(playQueueModel.rowCount()>1); - prevTrackAction->setEnabled(playQueueModel.rowCount()>1); + StdActions::self()->nextTrackAction->setEnabled(playQueueModel.rowCount()>1); + StdActions::self()->prevTrackAction->setEnabled(playQueueModel.rowCount()>1); #ifdef ENABLE_KDE_SUPPORT trayItem->setIconByName(Icons::self()->toolbarPauseIcon.name()); #else @@ -3026,21 +2999,21 @@ void MainWindow::updateNextTrack(int nextTrackId) if (-1!=nextTrackId && MPDState_Stopped==MPDStatus::self()->state()) { nextTrackId=-1; // nextSongId is not accurate if we are stopped. } - QString tt=nextTrackAction->property("tooltip").toString(); + QString tt=StdActions::self()->nextTrackAction->property("tooltip").toString(); if (-1==nextTrackId && tt.isEmpty()) { - nextTrackAction->setProperty("tooltip", nextTrackAction->toolTip()); + StdActions::self()->nextTrackAction->setProperty("tooltip", StdActions::self()->nextTrackAction->toolTip()); } else if (-1==nextTrackId) { - nextTrackAction->setToolTip(tt); - nextTrackAction->setProperty("trackid", nextTrackId); - } else if (nextTrackId!=nextTrackAction->property("trackid").toInt()) { + StdActions::self()->nextTrackAction->setToolTip(tt); + StdActions::self()->nextTrackAction->setProperty("trackid", nextTrackId); + } else if (nextTrackId!=StdActions::self()->nextTrackAction->property("trackid").toInt()) { Song s=playQueueModel.getSongByRow(playQueueModel.getRowById(nextTrackId)); if (!s.artist.isEmpty() && !s.title.isEmpty()) { tt+=QLatin1String("
")+s.artistSong()+QLatin1String(""); } else { nextTrackId=-1; } - nextTrackAction->setToolTip(tt); - nextTrackAction->setProperty("trackid", nextTrackId); + StdActions::self()->nextTrackAction->setToolTip(tt); + StdActions::self()->nextTrackAction->setProperty("trackid", nextTrackId); } } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 17085b35a..2170e8221 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -70,7 +70,6 @@ class DevicesPage; class QAbstractItemView; #ifndef Q_OS_WIN class Mpris; -class GnomeMediaKeys; #endif // !defined Q_OS_WIN class QTimer; class QPropertyAnimation; @@ -224,8 +223,6 @@ public Q_SLOTS: void stopAfterCurrentTrack(); void stopAfterTrack(); void playPauseTrack(); - void nextTrack(); - void prevTrack(); void setPosition(); void searchPlayQueue(); void realSearchPlayQueue(); @@ -330,14 +327,7 @@ private: Action *connectionsAction; Action *outputsAction; QActionGroup *connectionsGroup; - Action *prevTrackAction; - Action *nextTrackAction; - Action *playPauseTrackAction; - Action *stopPlaybackAction; - Action *stopAfterCurrentTrackAction; Action *stopAfterTrackAction; - Action *increaseVolumeAction; - Action *decreaseVolumeAction; Action *muteAction; Action *removeFromPlayQueueAction; Action *addPlayQueueToStoredPlaylistAction; @@ -399,9 +389,6 @@ private: #endif #ifndef Q_OS_WIN Mpris *mpris; - #ifndef ENABLE_KDE_SUPPORT - GnomeMediaKeys *gnomeMediaKeys; - #endif GtkProxyStyle *gtkStyle; #endif // Q_OS_WIN QTimer *statusTimer; diff --git a/gui/mediakeys.cpp b/gui/mediakeys.cpp new file mode 100644 index 000000000..e315ec193 --- /dev/null +++ b/gui/mediakeys.cpp @@ -0,0 +1,189 @@ +/* + * Cantata + * + * Copyright (c) 2011-2013 Craig Drummond + * + * ---- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "mediakeys.h" +#if !defined Q_OS_WIN && !defined Q_OS_MAC +#include "gnomemediakeys.h" +#endif +#if !defined Q_OS_MAC && QT_VERSION < 0x050000 +#include "qxtmediakeys.h" +#endif +#include "stdactions.h" +#include "settings.h" +#ifdef ENABLE_KDE_SUPPORT +K_GLOBAL_STATIC(MediaKeys, instance) +#endif + +MediaKeys * MediaKeys::self() +{ + #ifdef ENABLE_KDE_SUPPORT + return instance; + #else + static MediaKeys *instance=0; + if(!instance) { + instance=new MediaKeys; + } + return instance; + #endif +} + +QString MediaKeys::toString(InterfaceType i) +{ + switch (i) { + case NoInterface: + default: + return QString(); + case GnomeInteface: + return "gnome"; + case QxtInterface: + return "qxt"; + } +} + +MediaKeys::InterfaceType MediaKeys::toIface(const QString &i) +{ + #if defined Q_OS_MAC + return NoInterface; + #endif + + if (i==toString(GnomeInteface)) { + #if !defined Q_OS_WIN && !defined Q_OS_MAC + return GnomeInteface; + #else + return NoInterface; + #endif + } + + if (i==toString(QxtInterface)) { + #if QT_VERSION < 0x050000 + return QxtInterface; + #else + return NoInterface; + #endif + } + return NoInterface; +} + +MediaKeys::MediaKeys() +{ + #if !defined Q_OS_WIN && !defined Q_OS_MAC + gnome=0; + #endif + + #if !defined Q_OS_MAC && QT_VERSION < 0x050000 + qxt=0; + #endif +} + +MediaKeys::~MediaKeys() +{ + #if !defined Q_OS_MAC && QT_VERSION < 0x050000 + if (qxt) { + delete qxt; + } + #endif + #if !defined Q_OS_WIN && !defined Q_OS_MAC + if (gnome) { + delete gnome; + } + #endif +} + +void MediaKeys::load() +{ + InterfaceType current=NoInterface; + InterfaceType configured=toIface(Settings::self()->mediaKeysIface()); + #if !defined Q_OS_WIN && !defined Q_OS_MAC + if (gnome && gnome->isEnabled()) { + current=GnomeInteface; + } + #endif + + #if !defined Q_OS_MAC && QT_VERSION < 0x050000 + if (qxt && qxt->isEnabled()) { + current=QxtInterface; + } + #endif + + if (current==configured) { + return; + } + + #if !defined Q_OS_WIN && !defined Q_OS_MAC + if (gnome && GnomeInteface==current) { + disable(gnome); + gnome->deleteLater(); + gnome=0; + } + #endif + + #if !defined Q_OS_MAC && QT_VERSION < 0x050000 + if (qxt && QxtInterface==current) { + disable(qxt); + qxt->deleteLater(); + qxt=0; + } + #endif + + #if !defined Q_OS_WIN && !defined Q_OS_MAC + if (GnomeInteface==configured) { + if (!gnome) { + gnome=new GnomeMediaKeys(0); + } + enable(gnome); + } + #endif + + #if !defined Q_OS_MAC && QT_VERSION < 0x050000 + if (QxtInterface==configured) { + if (!qxt) { + qxt=new QxtMediaKeys(0); + } + enable(qxt); + } + #endif +} + +void MediaKeys::enable(MultiMediaKeysInterface *iface) +{ + if (!iface || iface->isEnabled()) { + return; + } + QObject::connect(iface, SIGNAL(playPause()), StdActions::self()->playPauseTrackAction, SIGNAL(triggered())); + QObject::connect(iface, SIGNAL(stop()), StdActions::self()->stopPlaybackAction, SIGNAL(triggered())); + QObject::connect(iface, SIGNAL(next()), StdActions::self()->nextTrackAction, SIGNAL(triggered())); + QObject::connect(iface, SIGNAL(previous()), StdActions::self()->prevTrackAction, SIGNAL(triggered())); + iface->setEnabled(true); +} + +void MediaKeys::disable(MultiMediaKeysInterface *iface) +{ + if (!iface || !iface->isEnabled()) { + return; + } + QObject::disconnect(iface, SIGNAL(playPause()), StdActions::self()->playPauseTrackAction, SIGNAL(triggered())); + QObject::disconnect(iface, SIGNAL(stop()), StdActions::self()->stopPlaybackAction, SIGNAL(triggered())); + QObject::disconnect(iface, SIGNAL(next()), StdActions::self()->nextTrackAction, SIGNAL(triggered())); + QObject::disconnect(iface, SIGNAL(previous()), StdActions::self()->prevTrackAction, SIGNAL(triggered())); + iface->setEnabled(false); +} diff --git a/gui/mediakeys.h b/gui/mediakeys.h new file mode 100644 index 000000000..257f68c3c --- /dev/null +++ b/gui/mediakeys.h @@ -0,0 +1,64 @@ +/* + * Cantata + * + * Copyright (c) 2011-2013 Craig Drummond + * + * ---- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef MEDIA_KEYS_H +#define MEDIA_KEYS_H + +#include + +class GnomeMediaKeys; +class QxtMediaKeys; +class MultiMediaKeysInterface; + +class MediaKeys +{ +public: + enum InterfaceType { + NoInterface, + GnomeInteface, + QxtInterface + }; + + static MediaKeys * self(); + static QString toString(InterfaceType i); + static InterfaceType toIface(const QString &i); + + MediaKeys(); + ~MediaKeys(); + + void load(); + +private: + void enable(MultiMediaKeysInterface *iface); + void disable(MultiMediaKeysInterface *iface); + +private: + #if !defined Q_OS_WIN && !defined Q_OS_MAC + GnomeMediaKeys *gnome; + #endif + #if !defined Q_OS_MAC && QT_VERSION < 0x050000 + QxtMediaKeys *qxt; + #endif +}; + +#endif diff --git a/gui/multimediakeysinterface.h b/gui/multimediakeysinterface.h new file mode 100644 index 000000000..6ddbb8b54 --- /dev/null +++ b/gui/multimediakeysinterface.h @@ -0,0 +1,52 @@ +/* + * Cantata + * + * Copyright (c) 2011-2013 Craig Drummond + * + * ---- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef MULTI_MEDIA_KEYS_INTERFACE_H +#define MULTI_MEDIA_KEYS_INTERFACE_H + +#include + +class MultiMediaKeysInterface : public QObject +{ + Q_OBJECT +public: + MultiMediaKeysInterface(QObject *p) : QObject(p), enabled(false) { } + ~MultiMediaKeysInterface() { } + + void setEnabled(bool e) { activate(e); enabled=e; } + bool isEnabled() const { return enabled; } + +private: + virtual void activate(bool a)=0; + +Q_SIGNALS: + void playPause(); + void stop(); + void next(); + void previous(); + +protected: + bool enabled; +}; + +#endif diff --git a/gui/preferencesdialog.cpp b/gui/preferencesdialog.cpp index 50e801500..41df741bd 100644 --- a/gui/preferencesdialog.cpp +++ b/gui/preferencesdialog.cpp @@ -50,6 +50,11 @@ #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND #include "audiocdsettings.h" #endif +#include "mediakeys.h" +#include +#include +#include +#include static int iCount=0; @@ -58,6 +63,73 @@ int PreferencesDialog::instanceCount() return iCount; } +#ifndef ENABLE_KDE_SUPPORT +class ShortcutsSettingsPage : public QWidget +{ +public: + ShortcutsSettingsPage(QWidget *p) + : QWidget(p) + , combo(0) + { + QBoxLayout *lay=new QBoxLayout(QBoxLayout::TopToBottom, this); + lay->setMargin(0); + + QHash map; + map.insert("Cantata", ActionCollection::get()); + shortcuts = new ShortcutsSettingsWidget(map, this); + shortcuts->view()->setAlternatingRowColors(false); + shortcuts->view()->setItemDelegate(new BasicItemDelegate(shortcuts->view())); + lay->addWidget(shortcuts); + + #if !defined Q_OS_MAC + #if QT_VERSION < 0x050000 || !defined Q_OS_WIN + QGroupBox *box=new QGroupBox(i18n("Multi-Media Keys")); + QBoxLayout *boxLay=new QBoxLayout(QBoxLayout::TopToBottom, box); + combo=new QComboBox(box); + boxLay->addWidget(combo); + combo->addItem(i18n("Disabled"), (unsigned int)MediaKeys::NoInterface); + #if QT_VERSION < 0x050000 + combo->addItem(i18n("Enabled"), (unsigned int)MediaKeys::QxtInterface); + #endif + #if !defined Q_OS_WIN + QByteArray desktop=qgetenv("XDG_CURRENT_DESKTOP"); + combo->addItem(desktop=="Unity" || desktop=="GNOME" + ? i18n("Use desktop settings") + : i18n("Use GNOME/Unity settings"), (unsigned int)MediaKeys::GnomeInteface); + #endif + lay->addWidget(box); + #endif // QT_VERSION < 0x050000 || !defined Q_OS_WIN + #endif // !defined Q_OS_MAC + } + + void load() + { + if (!combo) { + return; + } + unsigned int iface=(unsigned int)MediaKeys::toIface(Settings::self()->mediaKeysIface()); + for (int i=0; icount(); ++i) { + if (combo->itemData(i).toUInt()==iface) { + combo->setCurrentIndex(i); + break; + } + } + } + + void save() + { + shortcuts->save(); + if (combo) { + Settings::self()->saveMediaKeysIface(MediaKeys::toString((MediaKeys::InterfaceType)combo->itemData(combo->currentIndex()).toUInt())); + } + } + +private: + ShortcutsSettingsWidget *shortcuts; + QComboBox *combo; +}; +#endif + PreferencesDialog::PreferencesDialog(QWidget *parent) : Dialog(parent, "PreferencesDialog") { @@ -108,12 +180,9 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) widget->addPage(proxy, i18n("Proxy"), Icon("preferences-system-network"), i18nc("Qt-only", "Proxy Settings")); #endif #ifndef ENABLE_KDE_SUPPORT - QHash map; - map.insert("Cantata", ActionCollection::get()); - shortcuts = new ShortcutsSettingsPage(map, widget); + shortcuts = new ShortcutsSettingsPage(widget); widget->addPage(shortcuts, i18nc("Qt-only", "Shortcuts"), Icons::self()->shortcutsIcon, i18nc("Qt-only", "Keyboard Shortcut Settings")); - shortcuts->view()->setAlternatingRowColors(false); - shortcuts->view()->setItemDelegate(new BasicItemDelegate(shortcuts->view())); + shortcuts->load(); #endif widget->addPage(cache, i18n("Cache"), Icon("folder"), i18n("Cached Items")); setCaption(i18n("Configure")); diff --git a/gui/qxtmediakeys.cpp b/gui/qxtmediakeys.cpp new file mode 100644 index 000000000..6d06a8f4a --- /dev/null +++ b/gui/qxtmediakeys.cpp @@ -0,0 +1,66 @@ +/* + * Cantata + * + * Copyright (c) 2011-2013 Craig Drummond + * + * ---- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "qxtmediakeys.h" +#include "qxtglobalshortcut.h" + +QxtMediaKeys::QxtMediaKeys(QObject *p) + : MultiMediaKeysInterface(p) +{ +} + +void QxtMediaKeys::activate(bool a) +{ + if (a) { + createShortcuts(); + } else { + clear(); + } +} + +void QxtMediaKeys::createShortcuts() +{ + if (!shortcuts.isEmpty()) { + return; + } + QxtGlobalShortcut *shortcut = new QxtGlobalShortcut(Qt::Key_MediaPlay, this); + connect(shortcut, SIGNAL(activated()), this, SIGNAL(playPause())); + shortcuts.append(shortcut); + shortcut = new QxtGlobalShortcut(Qt::Key_MediaStop, this); + connect(shortcut, SIGNAL(activated()), this, SIGNAL(stop())); + shortcuts.append(shortcut); + shortcut = new QxtGlobalShortcut(Qt::Key_MediaNext, this); + connect(shortcut, SIGNAL(activated()), this, SIGNAL(next())); + shortcuts.append(shortcut); + shortcut = new QxtGlobalShortcut(Qt::Key_MediaPrevious, this); + connect(shortcut, SIGNAL(activated()), this, SIGNAL(previous())); + shortcuts.append(shortcut); +} + +void QxtMediaKeys::clear() +{ + if (!shortcuts.isEmpty()) { + qDeleteAll(shortcuts); + shortcuts.clear(); + } +} diff --git a/gui/qxtmediakeys.h b/gui/qxtmediakeys.h new file mode 100644 index 000000000..202e3c99d --- /dev/null +++ b/gui/qxtmediakeys.h @@ -0,0 +1,48 @@ +/* + * Cantata + * + * Copyright (c) 2011-2013 Craig Drummond + * + * ---- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef QXT_MEDIA_KEYS_H +#define QXT_MEDIA_KEYS_H + +#include "multimediakeysinterface.h" +#include + +class QxtGlobalShortcut; + +class QxtMediaKeys : public MultiMediaKeysInterface +{ +public: + QxtMediaKeys(QObject *p); + virtual ~QxtMediaKeys() { clear(); } + + void activate(bool a); + +private: + void createShortcuts(); + void clear(); + +private: + QList shortcuts; +}; + +#endif diff --git a/gui/settings.cpp b/gui/settings.cpp index 1499dfea8..4cbe18ddc 100644 --- a/gui/settings.cpp +++ b/gui/settings.cpp @@ -29,6 +29,7 @@ #include "itemview.h" #include "mpdparseutils.h" #include "utils.h" +#include "mediakeys.h" #ifdef ENABLE_KDE_SUPPORT #include #include @@ -525,12 +526,14 @@ QStringList Settings::hiddenPages() return GET_STRINGLIST("hiddenPages", def); } -#if !defined Q_OS_WIN && !defined ENABLE_KDE_SUPPORT -bool Settings::gnomeMediaKeys() +QString Settings::mediaKeysIface() { - return GET_BOOL("gnomeMediaKeys", true); + #if defined Q_OS_WIN + return GET_STRING("mediaKeysIface", MediaKeys::toString(MediaKeys::QxtInterface)); + #else + return GET_STRING("mediaKeysIface", MediaKeys::toString(MediaKeys::GnomeInteface)); + #endif } -#endif #ifdef ENABLE_DEVICES_SUPPORT bool Settings::overwriteSongs() @@ -1015,12 +1018,10 @@ void Settings::saveHiddenPages(const QStringList &v) SET_VALUE_MOD(hiddenPages) } -#if !defined Q_OS_WIN && !defined ENABLE_KDE_SUPPORT -void Settings::saveGnomeMediaKeys(bool v) +void Settings::saveMediaKeysIface(const QString &v) { - SET_VALUE_MOD(gnomeMediaKeys) + SET_VALUE_MOD(mediaKeysIface) } -#endif #ifdef ENABLE_DEVICES_SUPPORT void Settings::saveOverwriteSongs(bool v) diff --git a/gui/settings.h b/gui/settings.h index eaca8934d..21d8a3cf4 100644 --- a/gui/settings.h +++ b/gui/settings.h @@ -138,9 +138,7 @@ public: QByteArray contextSplitterState(); QString page(); QStringList hiddenPages(); - #if !defined Q_OS_WIN && !defined ENABLE_KDE_SUPPORT - bool gnomeMediaKeys(); - #endif + QString mediaKeysIface(); #ifdef ENABLE_DEVICES_SUPPORT bool overwriteSongs(); bool showDeleteAction(); @@ -233,9 +231,7 @@ public: void saveContextSplitterState(const QByteArray &v); void savePage(const QString &v); void saveHiddenPages(const QStringList &v); - #if !defined Q_OS_WIN && !defined ENABLE_KDE_SUPPORT - void saveGnomeMediaKeys(bool v); - #endif + void saveMediaKeysIface(const QString &v); #ifdef ENABLE_DEVICES_SUPPORT void saveOverwriteSongs(bool v); void saveShowDeleteAction(bool v); diff --git a/gui/stdactions.cpp b/gui/stdactions.cpp index 92d45f580..1adf59711 100644 --- a/gui/stdactions.cpp +++ b/gui/stdactions.cpp @@ -52,6 +52,14 @@ StdActions * StdActions::self() StdActions::StdActions() { + prevTrackAction = ActionCollection::get()->createAction("prevtrack", i18n("Previous Track"), Icons::self()->toolbarPrevIcon); + nextTrackAction = ActionCollection::get()->createAction("nexttrack", i18n("Next Track"), Icons::self()->toolbarNextIcon); + playPauseTrackAction = ActionCollection::get()->createAction("playpausetrack", i18n("Play/Pause"), Icons::self()->toolbarPlayIcon); + stopPlaybackAction = ActionCollection::get()->createAction("stopplayback", i18n("Stop"), Icons::self()->toolbarStopIcon); + stopAfterCurrentTrackAction = ActionCollection::get()->createAction("stopaftercurrenttrack", i18n("Stop After Current Track"), Icons::self()->toolbarStopIcon); + stopAfterTrackAction = ActionCollection::get()->createAction("stopaftertrack", i18n("Stop After Track"), Icons::self()->toolbarStopIcon); + increaseVolumeAction = ActionCollection::get()->createAction("increasevolume", i18n("Increase Volume")); + decreaseVolumeAction = ActionCollection::get()->createAction("decreasevolume", i18n("Decrease Volume")); savePlayQueueAction = ActionCollection::get()->createAction("saveplaylist", i18n("Save As"), "document-save-as"); addToPlayQueueAction = ActionCollection::get()->createAction("addtoplaylist", i18n("Add To Play Queue"), "list-add"); replacePlayQueueAction = ActionCollection::get()->createAction("replaceplaylist", i18n("Replace Play Queue"), "media-playback-start"); diff --git a/gui/stdactions.h b/gui/stdactions.h index 892541bd6..7770b430e 100644 --- a/gui/stdactions.h +++ b/gui/stdactions.h @@ -35,6 +35,14 @@ public: StdActions(); + Action *nextTrackAction; + Action *prevTrackAction; + Action *playPauseTrackAction; + Action *stopPlaybackAction; + Action *stopAfterCurrentTrackAction; + Action *stopAfterTrackAction; + Action *increaseVolumeAction; + Action *decreaseVolumeAction; Action *savePlayQueueAction; Action *addToPlayQueueAction; Action *replacePlayQueueAction; diff --git a/gui/trayitem.cpp b/gui/trayitem.cpp index acf485e53..794d40782 100644 --- a/gui/trayitem.cpp +++ b/gui/trayitem.cpp @@ -35,6 +35,7 @@ #include "action.h" #include "icons.h" #include "song.h" +#include "stdactions.h" TrayItem::TrayItem(MainWindow *p) : QObject(p) @@ -73,11 +74,11 @@ void TrayItem::setup() trayItem->setToolTip("cantata", i18n("Cantata"), QString()); trayItemMenu = new KMenu(0); - trayItemMenu->addAction(mw->prevTrackAction); - trayItemMenu->addAction(mw->playPauseTrackAction); - trayItemMenu->addAction(mw->stopPlaybackAction); - trayItemMenu->addAction(mw->stopAfterCurrentTrackAction); - trayItemMenu->addAction(mw->nextTrackAction); + trayItemMenu->addAction(StdActions::self()->prevTrackAction); + trayItemMenu->addAction(StdActions::self()->playPauseTrackAction); + trayItemMenu->addAction(StdActions::self()->stopPlaybackAction); + trayItemMenu->addAction(StdActions::self()->stopAfterCurrentTrackAction); + trayItemMenu->addAction(StdActions::self()->nextTrackAction); trayItem->setContextMenu(trayItemMenu); trayItem->setStatus(KStatusNotifierItem::Active); trayItemMenu->addSeparator(); @@ -94,11 +95,11 @@ void TrayItem::setup() trayItem = new QSystemTrayIcon(this); trayItem->installEventFilter(mw->volumeSliderEventHandler); trayItemMenu = new QMenu(0); - trayItemMenu->addAction(mw->prevTrackAction); - trayItemMenu->addAction(mw->playPauseTrackAction); - trayItemMenu->addAction(mw->stopPlaybackAction); - trayItemMenu->addAction(mw->stopAfterCurrentTrackAction); - trayItemMenu->addAction(mw->nextTrackAction); + trayItemMenu->addAction(StdActions::self()->prevTrackAction); + trayItemMenu->addAction(StdActions::self()->playPauseTrackAction); + trayItemMenu->addAction(StdActions::self()->stopPlaybackAction); + trayItemMenu->addAction(StdActions::self()->stopAfterCurrentTrackAction); + trayItemMenu->addAction(StdActions::self()->nextTrackAction); trayItemMenu->addSeparator(); trayItemMenu->addAction(mw->restoreAction); trayItemMenu->addSeparator(); @@ -125,9 +126,9 @@ void TrayItem::trayItemScrollRequested(int delta, Qt::Orientation orientation) { if (Qt::Vertical==orientation) { if (delta>0) { - mw->increaseVolumeAction->trigger(); + StdActions::self()->increaseVolumeAction->trigger(); } else if(delta<0) { - mw->decreaseVolumeAction->trigger(); + StdActions::self()->decreaseVolumeAction->trigger(); } } } diff --git a/support/shortcutssettingspage.cpp b/support/shortcutssettingspage.cpp index 1091d1bf0..e955cf2ec 100644 --- a/support/shortcutssettingspage.cpp +++ b/support/shortcutssettingspage.cpp @@ -53,7 +53,7 @@ bool ShortcutsFilter::filterAcceptsRow(int source_row, const QModelIndex &source /****************************************************************************/ -ShortcutsSettingsPage::ShortcutsSettingsPage(const QHash &actionCollections, QWidget *parent) +ShortcutsSettingsWidget::ShortcutsSettingsWidget(const QHash &actionCollections, QWidget *parent) : QWidget(parent), _shortcutsModel(new ShortcutsModel(actionCollections, this)), _shortcutsFilter(new ShortcutsFilter(this)) @@ -87,12 +87,12 @@ ShortcutsSettingsPage::ShortcutsSettingsPage(const QHashcurrentIndex().isValid() && shortcutsView->currentIndex().parent().isValid()) { QKeySequence active = shortcutsView->currentIndex().data(ShortcutsModel::ActiveShortcutRole).value(); QKeySequence def = shortcutsView->currentIndex().data(ShortcutsModel::DefaultShortcutRole).value(); @@ -113,11 +113,11 @@ void ShortcutsSettingsPage::setWidgetStates() { } } -void ShortcutsSettingsPage::on_searchEdit_textChanged(const QString &text) { +void ShortcutsSettingsWidget::on_searchEdit_textChanged(const QString &text) { _shortcutsFilter->setFilterString(text); } -void ShortcutsSettingsPage::keySequenceChanged(const QKeySequence &seq, const QModelIndex &conflicting) { +void ShortcutsSettingsWidget::keySequenceChanged(const QKeySequence &seq, const QModelIndex &conflicting) { if(conflicting.isValid()) _shortcutsModel->setData(conflicting, QKeySequence(), ShortcutsModel::ActiveShortcutRole); @@ -127,7 +127,7 @@ void ShortcutsSettingsPage::keySequenceChanged(const QKeySequence &seq, const QM setWidgetStates(); } -void ShortcutsSettingsPage::toggledCustomOrDefault() { +void ShortcutsSettingsWidget::toggledCustomOrDefault() { if(!shortcutsView->currentIndex().isValid()) return; @@ -142,6 +142,6 @@ void ShortcutsSettingsPage::toggledCustomOrDefault() { setWidgetStates(); } -void ShortcutsSettingsPage::save() { +void ShortcutsSettingsWidget::save() { _shortcutsModel->commit(); } diff --git a/support/shortcutssettingspage.h b/support/shortcutssettingspage.h index d4b2763a6..6a2bb69eb 100644 --- a/support/shortcutssettingspage.h +++ b/support/shortcutssettingspage.h @@ -42,10 +42,10 @@ private: QString _filterString; }; -class ShortcutsSettingsPage : public QWidget, private Ui::ShortcutsSettingsPage { +class ShortcutsSettingsWidget : public QWidget, private Ui::ShortcutsSettingsPage { Q_OBJECT public: - ShortcutsSettingsPage(const QHash &actionCollections, QWidget *parent = 0); + ShortcutsSettingsWidget(const QHash &actionCollections, QWidget *parent = 0); inline bool hasDefaults() const { return true; } QTreeView * view();